<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.delftsolutions.nl/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SleeplessByte</id>
	<title>Delft Solutions - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.delftsolutions.nl/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=SleeplessByte"/>
	<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/wiki/Special:Contributions/SleeplessByte"/>
	<updated>2026-04-04T00:11:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Error/OpusSafety::UnprocessableEntityError&amp;diff=640</id>
		<title>Error/OpusSafety::UnprocessableEntityError</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Error/OpusSafety::UnprocessableEntityError&amp;diff=640"/>
		<updated>2025-09-11T11:02:07Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;Unprocessable Entity Error&amp;#039;&amp;#039;&amp;#039; is an error Opus Compliance Cloud raises when the object you provided did not adhere to all constraints. This usually sets the response to a status code [https://http.cat/status/422 422: Unprocessable Entity].  == Common cause(s) ==  This error is seen when the server understands the request, and there are no authentication, authorization, conflict, or precondition errors. This generally means the error is with the actual content of the r...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Unprocessable Entity Error&#039;&#039;&#039; is an error Opus Compliance Cloud raises when the object you provided did not adhere to all constraints. This usually sets the response to a status code [https://http.cat/status/422 422: Unprocessable Entity].&lt;br /&gt;
&lt;br /&gt;
== Common cause(s) ==&lt;br /&gt;
&lt;br /&gt;
This error is seen when the server understands the request, and there are no authentication, authorization, conflict, or precondition errors. This generally means the error is with the actual content of the request.&lt;br /&gt;
&lt;br /&gt;
== Common resolution(s) ==&lt;br /&gt;
&lt;br /&gt;
The error message generally indicates the issue with the request. When the error message is generic, double check the request body and try again.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Error/OpusSafety::RequestFormatError&amp;diff=639</id>
		<title>Error/OpusSafety::RequestFormatError</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Error/OpusSafety::RequestFormatError&amp;diff=639"/>
		<updated>2025-09-11T10:59:56Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;Request Format Error&amp;#039;&amp;#039;&amp;#039; is an error Opus Compliance Cloud raises when The request has an invalid, incorrect, or incomplete format. This usually sets the response to a status code [https://http.cat/status/400 400: Bad Request].  == Common cause(s) ==  Usually caused because of the &amp;#039;&amp;#039;format&amp;#039;&amp;#039; of the request body (including URL query parameters), causing the system to be unable to &amp;#039;&amp;#039;parse&amp;#039;&amp;#039; the request. If the request is generally parseble but incorrect, a  Error/OpusS...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Request Format Error&#039;&#039;&#039; is an error Opus Compliance Cloud raises when The request has an invalid, incorrect, or incomplete format. This usually sets the response to a status code [https://http.cat/status/400 400: Bad Request].&lt;br /&gt;
&lt;br /&gt;
== Common cause(s) ==&lt;br /&gt;
&lt;br /&gt;
Usually caused because of the &#039;&#039;format&#039;&#039; of the request body (including URL query parameters), causing the system to be unable to &#039;&#039;parse&#039;&#039; the request. If the request is generally parseble but incorrect, a  [[Error/OpusSafety::UnprocessableEntityError|OpusSafety::UnprocessableEntityError]] is more common.&lt;br /&gt;
&lt;br /&gt;
== Common resolution(s) ==&lt;br /&gt;
&lt;br /&gt;
The error message generally indicates the issue with the request. When the error message is generic, double check the request body and try again.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=489</id>
		<title>Incident Handling</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=489"/>
		<updated>2024-11-06T15:36:44Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Critical incidents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zulip migration ==&lt;br /&gt;
Due to a migration to Zulip, the integration as was available on Mattermost is not available yet on Zulip. This leads to the following process changes:&lt;br /&gt;
* Acknowlegements and triggers resolving are not posted to Zulip by Zabbix&lt;br /&gt;
* Triggers are grouped in a topic on Zulip per host&lt;br /&gt;
* When an incident has been fully resolved, mark the topic as resolved, when any other incidents reported for the host are resolved&lt;br /&gt;
* There&#039;s no `?ongoing`, instead for now we can track open incidents by checking for unresolved topics&lt;br /&gt;
* The posting of incidents is less smart (only posting when not posted yet), so in order to prevent an incident from not being reported due to network issues or the likes, a message is posted after an inteval (8 hours for non-critical and lower, 1 hour for critical and above) while the incident has not been acknowleged.&lt;br /&gt;
* Incidents can be manually tracked by creating a topic by hand and reporting the problem&lt;br /&gt;
* There is no automatic gitlab issue creation or syncing anymore.&lt;br /&gt;
&lt;br /&gt;
Finally, where this process says to do something on Mattermost, you should now do so on Zulip. The updates in the process chapters themselves are WIP.&lt;br /&gt;
&lt;br /&gt;
== Critical incidents ==&lt;br /&gt;
&#039;&#039;&#039;Critical incidents are resolved within 16 hours.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As first responder you take on the responsiblity of seeing an incident resolved. This does not mean that you are the person required to do all the work. You can attempt to involve other to help you (often referred to as escalating the incident), but since other are not on-call, they are not obliged to help you, especially outside of normal working hours.&lt;br /&gt;
Involving multiple people can quickly be required if multiple critical incidents with different causes occur simultaniously. In that case, the First Responder usually takes on a more information management role and steers those that are brought on into resolving the issues. (Example: if a server crashes, several critical triggers can fire, but the underlying cause can quite quickly be determined to be a single issue, the crashed server. So you wouldn&#039;t need to call in people to manage each incident. But a client&#039;s service being down in one cluster while in a different cluster a different VM no longer boots is likely to be to different issues, so in order to resolve them on time you&#039;d want to call in help to resolve the incident in time).&lt;br /&gt;
&lt;br /&gt;
=== Process ===&lt;br /&gt;
The general process is made up of the folowing steps. Each step has additional information on how to handle/execute them in the sections below.&lt;br /&gt;
# Take responsibility for seeing the incident resolved&lt;br /&gt;
# Determine if incident is still ongoing&lt;br /&gt;
# If ongoing: Communicate to affected clients that the issue is being investigated&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# Resolve incident + cleanup&lt;br /&gt;
&lt;br /&gt;
During working on an incident it is expected that all communication is done in the incident&#039;s thread. This means all information to a problem can be found in a clear a predictable place. Sometimes an incident can be resolved by work done in another incident. In that case, it is required to post a link to that thread in the incident&#039;s thread with the comment that the resolution is done in that thread.&lt;br /&gt;
&lt;br /&gt;
==== Acknowledge the incident on Zabbix ====&lt;br /&gt;
The first step is to take responsibility for seeing the incident resolved by acknowledging the incident on Zabbix. Simply acknowledging the trigger suffices. It is however entirely possible that multiple critical incidents are firing at the same time. This can be a coincidence, or can be because of a share cause of failure. For example, a server crashing will cause server VM&#039; to reboot, or the router having an connectivity issue will lead to most other VM&#039;s having connectivity issues as well. If there are multiple critical incidents, it is advised to quickly observe what&#039;s ongoing, Zabbix is the best source of firing triggers for this, and pick the incident that is likely the root cause to  &lt;br /&gt;
&lt;br /&gt;
* Acknowledging an incident on Zabbix will stop Zabbix from calling the First Responder to notify them of the ongoing incident. And stops Zabbix from posting reminders on Zulip.&lt;br /&gt;
&lt;br /&gt;
==== Determine if incident is still ongoing ====&lt;br /&gt;
The next step is to check if the reported problem is still ongoing. Depending on the observations made here your process to follow and steps needed to resolve the incident can change. There are three options:&lt;br /&gt;
# The trigger resolved itself and the problem cannot be observed. Example: HTTPS is down for a site, but the FR can access the site through HTTPS without incident.&lt;br /&gt;
# The trigger resolved itself and the problem can still be observed.&lt;br /&gt;
# The trigger is still firing but the problem cannot be observed: Our triggers might not be perfect, so it could be that something else is causing it to fire. A simple example would be that Zabbix reports that the the DNS for a site can&#039;t be resolved, but in reality there&#039;s a bug in the script we wrote that checks if the DNS resolves and the DNS resolves fine. Final note: keep in mind that an &#039;it works on my machine&#039; does not necessarily mean it works for most other people, so depening on the trigger you need to do some evaluations if your tests suffice. &lt;br /&gt;
&lt;br /&gt;
In order to make sure you are actually trying to observe the same thing as the trigger is looking for, make sure to check the trigger definition and the current data of the associated item(s). Some triggers might fire if one of multiple conditions is met (Such as a trigger that monitors the ping response time firing if the value exceeds a certain threshold, or if no data for a certain period of time was observed).&lt;br /&gt;
&lt;br /&gt;
Make sure to report your findings in the incident&#039;s thread. It&#039;s advised to post a screenshot of the relevant item(s) and your own observations. (Continuing the ping example, you would post a screenshot of the relevant values, state your conclusion why the trigger is firing, and your own observations/pings)&lt;br /&gt;
&lt;br /&gt;
==== Communicate to affected clients ====&lt;br /&gt;
If the incident is still ongoing and the service is down, we need to communicate to affected clients that we are aware of the problem and that we are investigating it. This is because critical incident usually mean the service is down, something the clients can notice/are affected by, so we to be transparent that something is going on. There are some additional notes to this though:&lt;br /&gt;
* If an incident has already resolved itself and the problem is no longer observable, we don&#039;t communicate anything. Doing so might only cause confusion, and since the client has not reported any issues, they have not had a noticeable problem with it themselves.&lt;br /&gt;
* Although a critical incident generally means that the client service is down or experiencing reduced service, not all critical incidents are of that nature. Some are more administrative, or are only an issue for Delft Solutions itself. As of writing I don&#039;t have an exhaustive list, but here is those I can think of:&lt;br /&gt;
** SSH Service is down: We don&#039;t have any clients that SSH into their services, so it&#039;s generally not a problem. But SSH is mostly used for SRE maintenance and publishing new builds. The SRE maintenance is an internal problem, so no need to communicate to the client. The publishing is done to Kaboom, preventing new builds from being published, and the two SM VM&#039;s.&lt;br /&gt;
** No backup for x days: Clients don&#039;t notice it if a backup is running late, so no need to communicate with clients. Just need to make sure the backup gets completed&lt;br /&gt;
** SSL certificate is expiring in &amp;lt; 24 hours: This is a bit dependent on how soon this incident is being handled, but if it handled quickly, the certificate never actually expired, and there has not been any disruption to the client&#039;s service, so no need for communicating about it.&lt;br /&gt;
* Determining which clients are being affected can be done by looking at the host&#039;s DNS in the trigger, and/or looking up the VM in Proxmox and checking the tags of the VM&#039;s for client names. In the case that this issue is causing multiple other critical triggers to fire, you would have to check for which clients are affected by those incidents.&lt;br /&gt;
* Communicating to DS about ongoing incidents is usually assumed to be automaticly have been done by the fact that the incident was reported on Zulip.&lt;br /&gt;
&lt;br /&gt;
As always, report the decisions taken and actions maded in the incident thread. (e.g.: I&#039;ve sent a message in the Slack to let Kaboom know that we aware of problem x, and that we are investigating it)&lt;br /&gt;
&lt;br /&gt;
==== Communicate plan/next steps + Communicate findings/results of executed plan ====&lt;br /&gt;
This is the main part of handling an incident. There are several actions you can take in these steps, but at the basis they consist of sharing your next steps, performing those, and reporting the results. The reason all this needs to be reported is to ensure that all known information about a problem is logged, making it easier for someone else to be onboarded into the issue, for later reference if a similar issue is encountered, and even for use during the incident itself in case an older configuration needs to be referenced after you changed it.&lt;br /&gt;
The objective from these steps is determining what is actually wrong and how to resolve it. Depending on the observations made earlier on whether the incident is still ongoing and is (still) observable your investigation can go into different directions. (e.g. Find the underlying cause for a trigger, or determining why the trigger is firing while it likely shouldn&#039;t, and then how to resolve that underlying cause or how to update the trigger to work better)&lt;br /&gt;
&lt;br /&gt;
There are three main types of steps defined, but you are not limited to these:&lt;br /&gt;
# Hypothesis: If you have an idea what could be causing it, you would state your hypothesis and your next step would be to prove that hypothesis. For example, for an incident &#039;SSH service is down on X&#039; your hypothesis could be that this is due to &#039;MaxStartups&#039; throttling, which can be proven by &#039;grep&#039;ing journalctl for that, and compare the start and end times of throttling with the timestamps of the item reporting the status of the SSH service.&lt;br /&gt;
# Information gathering: Sometimes it just helps to get some facts about the situation collected. What is usefull information that is relevant depends on the triggers, but some examples are: The syslog/journalctl of the host from around the time of the incident (it can contain a reference to the an underlying problem in various levels of explicitness), the ping response from several hosts on the route to a host or a traceroute (this helps with networking issues). The gathered information is usually intended to help you come up with an hypothesis on what&#039;s wrong.&lt;br /&gt;
# Investigative: The most rigorous of process. The full process is described here originally [https://docs.google.com/document/d/1AQYJM1Q9l2Tyk6zfCVaQ2aEq-dpbfUH5okE88bpKkhw/edit#heading=h.5fq2skijqbdc Drive - Final Coundown - General Investigative Process]. To summarize, when you don&#039;t know why something is failing, and/or don&#039;t have any decent hypotheses to follow up, you can follow this process to systematicly find the problem.&lt;br /&gt;
&lt;br /&gt;
Regarding the resolution to an incident: The resolution to any incident is usually one of two things:&lt;br /&gt;
# Fix the underlying problem.&lt;br /&gt;
# Fix the trigger itself.&lt;br /&gt;
Fixing the trigger is relavively straightforward, but do make sure document in the thread what you changed to which trigger.&lt;br /&gt;
Fixing the underlying problem can be more complex. A trade-off needs to be made sometimes between resolving technical debt, or simply patching the current system to resolve the issue. We usually look for a resolution that ensures that the problem won&#039;t re-occur soon, or makes it unexpected/unlikely for the problem to re-occur. Taking into account the timeframe that is available to resolve the incident you can make some trade-offs. An example would be: normal backups of VM&#039;s are failing due to the Proxmox backup server being down/unreachable and it is determined that this cannot be resolved at that moment. We can set up automatic backups to local storage temporary to resolve the immediate problem and ensure we keep our SLO&#039;s versus setting up a new Proxmox Backup server at a different location. Since we don&#039;t have much time to resolve the problem, the resolution would be to set up the automatic backups to local storage, and set up a new Proxmox Backup Server later as a seperate issue.&lt;br /&gt;
&lt;br /&gt;
Some know issues and their resolutions:&lt;br /&gt;
* SSH service is down: The internet is a vile place. There&#039;s constant port scanning and hacking attempts ongoing to any machine connected to the internet (mostly IPv4). Due to this, SSH has a throttling functionality build in to prevent a system from being DDOS&#039;ed by the amount of malicious SSH requests. This throttling can cause the Zabbix server from being denied an SSH connection, of which several failures fire this trigger. This hypothesis can be proven with a `journalctl -u ssh | grep &#039;MaxStartupsThrottling&#039;` (you probably want to select a relevant time period with `--since &amp;quot;2 hours ago&amp;quot;` or something similar to prevent having to process a month of logging). You can then compare the throttling start and end times with the timestamps of the item data itself. The resolution for the issue is to add our custom ssh configuration [https://chat.dsinternal.net/#narrow/stream/23-SRE---General/topic/DS.20Whitelisted.20Custom.20SSH.20configuration/near/1620 Custom SSH Configuration].&lt;br /&gt;
* No backup for 3 days: Are S3 backup is very slow. Not much to prove as an underlying issue here. What needs to be done is check that the backup process is ongoing. The Zabbix latest data can be checked to verify that backups are running by checking that that days backups were done for the smaller buckets. The devteam email can be checked for if the backup process could not start on day due to it already running (it takes 24+ hours, and an attempt to start it is done each day by cron).&lt;br /&gt;
* git.* HTTPS is down: On Sunday mostly, Gitlab gets automaticly updated, but this incurs some downtime as the service is restarted. This is usually short enough to not be reported to Zulip as per our settings, but sometimes it&#039;s longer. If the service does not stay down, the issue can be just resolved.&lt;br /&gt;
&lt;br /&gt;
==== Resolve incident + cleanup ====&lt;br /&gt;
When you&#039;ve executed and verified the resolution in the previous steps we can proceed resolving the issue in our Mattermost integration. Resolving an incident can be done by doing the following:&lt;br /&gt;
# Verify that the trigger is no longer firing. An incident will be immediatly re-opened if the trigger is still firing, and the incident cannot be considered resolved if the trigger is still firing. If the trigger is still firing but you&#039;re sure that you&#039;ve resolved the problem, you might need to force the item the trigger depends on to update. This can be done by finding the item in the host&#039;s configuration on Zabbix and selecting &#039;Execute Now&#039;, after a short period this should force Zabbix to re-execute the item. You can check the timestamps in the latest data of an item to check if it was updated.&lt;br /&gt;
# Close the incident by marking the topic as resolved, when there are no other triggers firing for the host.&lt;br /&gt;
&lt;br /&gt;
Unfortunatly, some problems cause multiple critical and non-critical triggers to fire. This means we have to check Zabbix and Zulip for other fired triggers and ongoing incidents. The goal is to identify critical and non-critical incidents that were caused by the incident/underlying issue you just resolved.&lt;br /&gt;
# First, these incidents need to be acknowledged on Zabbix, and in the acknowledgement message you mention the incident/problem that caused this.&lt;br /&gt;
# Next, check the incident tracked by the integration on Mattermost using the `?ongoing` command. Resolve incidents that were (re-)opened by this incident by executing the following steps. If the first two fail (problem still persists, trigger is still firing), the incident needs to considered it&#039;s own issue and the relevant process needs to be followed (critical or non-critical depending on criticality).&lt;br /&gt;
## Ensuring the mentioned problem is no longer observable&lt;br /&gt;
## The trigger has resolved (You might need to force an update with `Execute Now`).&lt;br /&gt;
## Posting a link to the main incident you resolved with the comment that the underlying problem was resolved in that topic.&lt;br /&gt;
## Closing the incident by marking the topic as resolved, when there are no other triggers firing for the host.&lt;br /&gt;
&lt;br /&gt;
When you are done, there should be no more critical triggers firing in Zabbix or open in the Zabbix-Mattermost intergration, for which no-one has taken responsibility or you have taken responsibility for and are not actively handling.&lt;br /&gt;
&lt;br /&gt;
===Additional context===&lt;br /&gt;
* Critical incidents are posted in [https://chat.dsinternal.net/#narrow/stream/24-SRE-.23-Critical &#039;&#039;&#039;SLA - Critical&#039;&#039;&#039;].&lt;br /&gt;
* &amp;lt;s&amp;gt;When it is being tracked on GitLab a heavy check mark is added to the message.&amp;lt;/s&amp;gt;&lt;br /&gt;
* &amp;lt;s&amp;gt;Responses on the thread and on GitLab are automatically synced (to some extend)&amp;lt;/s&amp;gt;&lt;br /&gt;
* &amp;lt;s&amp;gt;When you reply with &#039;&#039;&#039;I agree that this has been fully resolved&#039;&#039;&#039; eventually our Zabbix-Mattermost integration will pick this up and a green check mark is added to the message.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Non-Critical incidents ==&lt;br /&gt;
* Non-critical incidents are acknowledged within 9 hours and resolved within one week.&lt;br /&gt;
&lt;br /&gt;
=== Acknowledging ===&lt;br /&gt;
Fully acknowledging a non-critical incident requires the following tasks to have been completed:&lt;br /&gt;
* Acknowledging the incident on Zabbix&lt;br /&gt;
* Add the non-critical incident as a milestone in the metrics sheet&lt;br /&gt;
** Start date is the date of the incident&lt;br /&gt;
** DoD states what needs to be true for the non-critical incident to be consider resolved&lt;br /&gt;
* Add the non-critical incident to Lynx as a project&lt;br /&gt;
** Tasks need to be added&lt;br /&gt;
** Final tasks needs to have the SLO deadline set as &#039;contraint&#039;&lt;br /&gt;
** Project priority is set to 20 (as a default)&lt;br /&gt;
** The tasks are estimated for SP&lt;br /&gt;
* The Lynx project ID is reported in the non-critical incident&#039;s topic on Zulip&lt;br /&gt;
* A Kimai activity is created in Kimai for the non-critical incident&lt;br /&gt;
&lt;br /&gt;
Checklist (outdated)&lt;br /&gt;
# Acknowledge on Zabbix and state who is responsible for resolving this in the description&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# If there is no resolution to the incident, evaluate if the trigger needs updating/disabling&lt;br /&gt;
# Resolve incident&lt;br /&gt;
&lt;br /&gt;
== Informational incidents ==&lt;br /&gt;
* Informational incidents are acknowledged within 72 hours&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix&lt;br /&gt;
# Sanity check the event, post result in thread&lt;br /&gt;
# If action needed, perform action&lt;br /&gt;
&lt;br /&gt;
== If an incident is reported by other means than the Zabbix-Zulip intergration ==&lt;br /&gt;
# Acknowledge receipt.&lt;br /&gt;
# Classify the incident as critical, non-critical, or informational.&lt;br /&gt;
# Create an topic in the relevant SRE channel, stating the problem and that you is responsible for resolving it.&lt;br /&gt;
# Proceed to treat the incident according to the criticality you just classified it as. (So for a critical incident, it means you now start the critical incident handling process)&lt;br /&gt;
&lt;br /&gt;
== Handover ==&lt;br /&gt;
When handing over the responsibility of &#039;&#039;&#039;first responder&#039;&#039;&#039; (FR), the following needs to happen:&lt;br /&gt;
* The handover can be initiated by both the upcoming FR or the acting FR&lt;br /&gt;
* Acting FR adds the upcoming FR the the IPA sla-first-responder user group and enables Zabbix calling for that the upcoming FR if they have that set by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; [https://status.delftinfra.net/zabbix/actionconf.php?eventsource=0# Trigger actions]&lt;br /&gt;
* The upcoming FR makes sure they are aware of the state of the SLA and knows what questions they wants to ask the acting FR.&lt;br /&gt;
* The upcoming FR makes sure they are subscribed to the right channels&lt;br /&gt;
&lt;br /&gt;
The following steps can be done async or in person:&lt;br /&gt;
* The acting FR announces/informs the upcoming FR has been added to the sla-first-responder group (In Zulip&#039;s [https://chat.dsinternal.net/#narrow/stream/13-Organisational Organisational channel] if asynq).&lt;br /&gt;
* If the acting FR wants to hand over responsibility for any ongoing incident they also state which incidents they want the upcoming FR to take over.&lt;br /&gt;
* If there are any particularities the upcoming FR needs to be aware of, those are shared.&lt;br /&gt;
* The upcoming FR asks their questions until they are satisfied and able to take over the FR&lt;br /&gt;
* The upcoming FR ensures they are subscribed to the following channels on Zulip: [https://chat.dsinternal.net/#narrow/stream/23-SRE---General SRE - General], [https://chat.dsinternal.net/#narrow/stream/24-SRE-.23-Critical SRE # Critical] and if part of the SRE team [https://chat.dsinternal.net/#streams/4/SRE%20##%20Non-critical SRE ## Non-Critical] and [https://chat.dsinternal.net/#streams/5/SRE%20###%20Informational SRE ### Informational].&lt;br /&gt;
* The upcoming FR announces/informs that they are now the acting FR over Zulip&#039;s [https://chat.dsinternal.net/#narrow/stream/13-Organisational Organisational channel]&lt;br /&gt;
* The now acting FR removes the previous FR from IPA the sla-first-responder user group and disables Zabbix calling for the previous FR if they had that enabled by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; [https://status.delftinfra.net/zabbix/actionconf.php?eventsource=0# Trigger actions]&lt;br /&gt;
&lt;br /&gt;
===Checklist for Handing Over First Responder (FR) Responsibilities===&lt;br /&gt;
&lt;br /&gt;
When transferring the role of First Responder (FR), follow these steps:&lt;br /&gt;
&lt;br /&gt;
1. Initiate the Handover:&lt;br /&gt;
   - Acting FR or Upcoming FR*: Initiate the handover process.&lt;br /&gt;
&lt;br /&gt;
2. Add Upcoming FR to User Group and Enable Zabbix Calling:&lt;br /&gt;
   - Acting FR:&lt;br /&gt;
     - Add the upcoming FR to the IPA `sla-first-responder` user group.&lt;br /&gt;
     - Enable Zabbix calling for the upcoming FR (if applicable) by navigating to:&lt;br /&gt;
       - Zabbix&amp;gt; Configuration &amp;gt; Actions &amp;gt; [Trigger actions](https://status.delftinfra.net/zabbix/actionconf.php?eventsource=0#).&lt;br /&gt;
&lt;br /&gt;
3. Announce Addition to User Group:&lt;br /&gt;
   - Acting FR:&lt;br /&gt;
     - Inform the upcoming FR that they have been added to the `sla-first-responder` group.&lt;br /&gt;
     - If communicating asynchronously, announce this in Zulip&#039;s [Organisational channel](https://chat.dsinternal.net/#narrow/stream/13-Organisational).&lt;br /&gt;
&lt;br /&gt;
4. Communicate Ongoing Incidents and Particularities:&lt;br /&gt;
   - Acting FR:&lt;br /&gt;
     - Share details of any ongoing incidents to be handed over.&lt;br /&gt;
     - Inform the upcoming FR of any specific details they need to be aware of.&lt;br /&gt;
&lt;br /&gt;
5. Review SLA State and Prepare Questions:&lt;br /&gt;
   - Upcoming FR:&lt;br /&gt;
      - Familiarize yourself with the current state of the SLA.&lt;br /&gt;
      - Prepare any questions for the acting FR.&lt;br /&gt;
&lt;br /&gt;
6. Clarify and Confirm Understanding:&lt;br /&gt;
   - Upcoming FR:&lt;br /&gt;
     - Ask all necessary questions until you are confident in taking over the FR role.&lt;br /&gt;
&lt;br /&gt;
7. Subscribe to Relevant Zulip Channels:&lt;br /&gt;
   - Upcoming FR:&lt;br /&gt;
     - Subscribe to the following channels:&lt;br /&gt;
       - [SRE - General](https://chat.dsinternal.net/#narrow/stream/23-SRE---General)&lt;br /&gt;
       - [SRE # Critical](https://chat.dsinternal.net/#narrow/stream/24-SRE-.23-Critical)&lt;br /&gt;
     - If part of the SRE team, also subscribe to:&lt;br /&gt;
       - [SRE ## Non-Critical](https://chat.dsinternal.net/#streams/4/SRE%20##%20Non-critical)&lt;br /&gt;
       - [SRE ### Informational](https://chat.dsinternal.net/#streams/5/SRE%20###%20Informational)&lt;br /&gt;
&lt;br /&gt;
8. Announce Acceptance of FR Role:&lt;br /&gt;
   - Upcoming FR (now Acting FR):&lt;br /&gt;
     - Announce that you are now the acting FR in Zulip&#039;s [Organisational channel](https://chat.dsinternal.net/#narrow/stream/13-Organisational).&lt;br /&gt;
&lt;br /&gt;
9. Remove Previous FR from User Group and Disable Zabbix Calling:&lt;br /&gt;
   - Now Acting FR:&lt;br /&gt;
     - Remove the previous FR from the IPA `sla-first-responder` user group.&lt;br /&gt;
     - Disable Zabbix calling for the previous FR by navigating to:&lt;br /&gt;
       - Zabbix&amp;gt; Configuration &amp;gt; Actions &amp;gt; [Trigger actions](https://status.delftinfra.net/zabbix/actionconf.php?eventsource=0#).&lt;br /&gt;
     - Ensure the previous FR&#039;s phone number is disabled in Zabbix calling settings.&lt;br /&gt;
&lt;br /&gt;
10. Confirm Completion of Handover:&lt;br /&gt;
    - Now Acting FR:&lt;br /&gt;
      - Verify that all steps have been completed and the handover is fully executed.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=393</id>
		<title>MediaWiki:Mobile.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=393"/>
		<updated>2024-07-21T23:31:54Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Fix double close&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* All CSS here will be loaded for users of the mobile site */&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
	display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
    justify-content: start;&lt;br /&gt;
    padding-top: 70px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel {&lt;br /&gt;
	position: relative;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: beige;&lt;br /&gt;
    border-bottom: 1px solid black;&lt;br /&gt;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, .2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-head, #p-personal {&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#left-navigation, #right-navigation, .vector-menu-tabs-legacy, .vector-search-box {&lt;br /&gt;
    float: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#left-navigation {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
	margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal ul {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer, #content {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=392</id>
		<title>MediaWiki:Mobile.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=392"/>
		<updated>2024-07-21T23:30:55Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Remove indentation for menu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* All CSS here will be loaded for users of the mobile site */&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
	display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
    justify-content: start;&lt;br /&gt;
    padding-top: 70px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel {&lt;br /&gt;
	position: relative;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: beige;&lt;br /&gt;
    border-bottom: 1px solid black;&lt;br /&gt;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, .2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-head, #p-personal {&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#left-navigation, #right-navigation, .vector-menu-tabs-legacy, .vector-search-box {&lt;br /&gt;
    float: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#left-navigation {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
	margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-personal ul {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer, #content {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=391</id>
		<title>MediaWiki:Mobile.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=391"/>
		<updated>2024-07-21T23:28:44Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Stop floating all the things&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* All CSS here will be loaded for users of the mobile site */&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
	display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
    justify-content: start;&lt;br /&gt;
    padding-top: 70px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel {&lt;br /&gt;
	position: relative;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: beige;&lt;br /&gt;
    border-bottom: 1px solid black;&lt;br /&gt;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, .2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-head, #p-personal {&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#left-navigation, #right-navigation, .vector-menu-tabs-legacy, .vector-search-box {&lt;br /&gt;
 float: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer, #content {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=390</id>
		<title>MediaWiki:Mobile.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=390"/>
		<updated>2024-07-21T23:25:59Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Probably make the site work on mobile&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* All CSS here will be loaded for users of the mobile site */&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
	display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
    justify-content: start;&lt;br /&gt;
    padding-top: 70px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel {&lt;br /&gt;
	position: relative;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: beige;&lt;br /&gt;
    border-bottom: 1px solid black;&lt;br /&gt;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, .2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer, #content {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=389</id>
		<title>MediaWiki:Mobile.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=389"/>
		<updated>2024-07-21T23:19:02Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Make menu available on mobile&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* All CSS here will be loaded for users of the mobile site */&lt;br /&gt;
&lt;br /&gt;
#mw-head {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel {&lt;br /&gt;
	position: relative;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: beige;&lt;br /&gt;
    border-bottom: 1px solid black;&lt;br /&gt;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, .2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer, #content {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Retrospectives&amp;diff=374</id>
		<title>Retrospectives</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Retrospectives&amp;diff=374"/>
		<updated>2024-07-05T17:27:40Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions most teams will hold a retrospective each week to see where process can be improved.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
During the week, issues with the current process (for example a process not being followed by someone, or a process not taking care of a specific incident) will be listed in the [https://chat.dsinternal.net/#narrow/stream/15-Retro Retro channel]. Once a week, generally on Friday, these points are discussed in a timeboxed meeting. There is &#039;&#039;always&#039;&#039; an outcome to each item, where everyone in the team agrees that is how we wil move forward. That means that we cannot just do nothing, but we can &#039;&#039;decide&#039;&#039; to not change anything (and have it happen again next time). In most cases the resolution will be to amend the process at hand.&lt;br /&gt;
&lt;br /&gt;
This also means that you cannot diverge from a current process &#039;&#039;during&#039;&#039; the week, but only after discussing it at the Retrospective.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=373</id>
		<title>Incident Handling</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=373"/>
		<updated>2024-07-05T17:23:16Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Add retrospective point information about required channels.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zulip migration ==&lt;br /&gt;
Due to a migration to Zulip, the integration as was available on Mattermost is not available yet on Zulip. This leads to the following process changes:&lt;br /&gt;
* Acknowlegements and triggers resolving are not posted to Zulip by Zabbix&lt;br /&gt;
* Triggers are grouped in a topic on Zulip per host&lt;br /&gt;
* When an incident has been fully resolved, mark the topic as resolved, when any other incidents reported for the host are resolved&lt;br /&gt;
* There&#039;s no `?ongoing`, instead for now we can track open incidents by checking for unresolved topics&lt;br /&gt;
* The posting of incidents is less smart (only posting when not posted yet), so in order to prevent an incident from not being reported due to network issues or the likes, a message is posted after an inteval (8 hours for non-critical and lower, 1 hour for critical and above) while the incident has not been acknowleged.&lt;br /&gt;
* Incidents can be manually tracked by creating a topic by hand and reporting the problem&lt;br /&gt;
* There is no automatic gitlab issue creation or syncing anymore.&lt;br /&gt;
&lt;br /&gt;
Finally, where this process says to do something on Mattermost, you should now do so on Zulip. The updates in the process chapters themselves are WIP.&lt;br /&gt;
&lt;br /&gt;
== Critical incidents ==&lt;br /&gt;
* Critical incidents are resolved within 16 hours.&lt;br /&gt;
&lt;br /&gt;
As first responder you take on the responsiblity of seeing an incident resolved. This does not mean that you are the person required to do all the work. You can attempt to involve other to help you (often referred to as escalating the incident), but since other are not on-call, they are not obliged to help you, especially outside of normal working hours.&lt;br /&gt;
Involving multiple people can quickly be required if multiple critical incidents with different causes occur simultaniously. In that case, the First Responder usually takes on a more information management role and steers those that are brought on into resolving the issues. (Example: if a server crashes, several critical triggers can fire, but the underlying cause can quite quickly be determined to be a single issue, the crashed server. So you wouldn&#039;t need to call in people to manage each incident. But a client&#039;s service being down in one cluster while in a different cluster a different VM no longer boots is likely to be to different issues, so in order to resolve them on time you&#039;d want to call in help to resolve the incident in time).&lt;br /&gt;
&lt;br /&gt;
=== Process ===&lt;br /&gt;
The general process is made up of the folowing steps. Each step has additional information on how to handle/execute them in the sections below.&lt;br /&gt;
# Take responsibility for seeing the incident resolved&lt;br /&gt;
# Determine if incident is still ongoing&lt;br /&gt;
# If ongoing: Communicate to affected clients that the issue is being investigated&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# Resolve incident + cleanup&lt;br /&gt;
&lt;br /&gt;
During working on an incident it is expected that all communication is done in the incident&#039;s thread. This means all information to a problem can be found in a clear a predictable place. Sometimes an incident can be resolved by work done in another incident. In that case, it is required to post a link to that thread in the incident&#039;s thread with the comment that the resolution is done in that thread.&lt;br /&gt;
&lt;br /&gt;
==== Acknowledge the incident on Zabbix ====&lt;br /&gt;
The first step is to take responsibility for seeing the incident resolved by acknowledging the incident on Zabbix. Simply acknowledging the trigger suffices. It is however entirely possible that multiple critical incidents are firing at the same time. This can be a coincidence, or can be because of a share cause of failure. For example, a server crashing will cause server VM&#039; to reboot, or the router having an connectivity issue will lead to most other VM&#039;s having connectivity issues as well. If there are multiple critical incidents, it is advised to quickly observe what&#039;s ongoing, Zabbix is the best source of firing triggers for this, and pick the incident that is likely the root cause to  &lt;br /&gt;
&lt;br /&gt;
* Acknowledging an incident on Zabbix will stop Zabbix from calling the First Responder to notify them of the ongoing incident. And stops Zabbix from posting reminders on Zulip.&lt;br /&gt;
&lt;br /&gt;
==== Determine if incident is still ongoing ====&lt;br /&gt;
The next step is to check if the reported problem is still ongoing. Depending on the observations made here your process to follow and steps needed to resolve the incident can change. There are three options:&lt;br /&gt;
# The trigger resolved itself and the problem cannot be observed. Example: HTTPS is down for a site, but the FR can access the site through HTTPS without incident.&lt;br /&gt;
# The trigger resolved itself and the problem can still be observed.&lt;br /&gt;
# The trigger is still firing but the problem cannot be observed: Our triggers might not be perfect, so it could be that something else is causing it to fire. A simple example would be that Zabbix reports that the the DNS for a site can&#039;t be resolved, but in reality there&#039;s a bug in the script we wrote that checks if the DNS resolves and the DNS resolves fine. Final note: keep in mind that an &#039;it works on my machine&#039; does not necessarily mean it works for most other people, so depening on the trigger you need to do some evaluations if your tests suffice. &lt;br /&gt;
&lt;br /&gt;
In order to make sure you are actually trying to observe the same thing as the trigger is looking for, make sure to check the trigger definition and the current data of the associated item(s). Some triggers might fire if one of multiple conditions is met (Such as a trigger that monitors the ping response time firing if the value exceeds a certain threshold, or if no data for a certain period of time was observed).&lt;br /&gt;
&lt;br /&gt;
Make sure to report your findings in the incident&#039;s thread. It&#039;s advised to post a screenshot of the relevant item(s) and your own observations. (Continuing the ping example, you would post a screenshot of the relevant values, state your conclusion why the trigger is firing, and your own observations/pings)&lt;br /&gt;
&lt;br /&gt;
==== Communicate to affected clients ====&lt;br /&gt;
If the incident is still ongoing and the service is down, we need to communicate to affected clients that we are aware of the problem and that we are investigating it. This is because critical incident usually mean the service is down, something the clients can notice/are affected by, so we to be transparent that something is going on. There are some additional notes to this though:&lt;br /&gt;
* If an incident has already resolved itself and the problem is no longer observable, we don&#039;t communicate anything. Doing so might only cause confusion, and since the client has not reported any issues, they have not had a noticeable problem with it themselves.&lt;br /&gt;
* Although a critical incident generally means that the client service is down or experiencing reduced service, not all critical incidents are of that nature. Some are more administrative, or are only an issue for Delft Solutions itself. As of writing I don&#039;t have an exhaustive list, but here is those I can think of:&lt;br /&gt;
** SSH Service is down: We don&#039;t have any clients that SSH into their services, so it&#039;s generally not a problem. But SSH is mostly used for SRE maintenance and publishing new builds. The SRE maintenance is an internal problem, so no need to communicate to the client. The publishing is done to Kaboom, preventing new builds from being published, and the two SM VM&#039;s.&lt;br /&gt;
** No backup for x days: Clients don&#039;t notice it if a backup is running late, so no need to communicate with clients. Just need to make sure the backup gets completed&lt;br /&gt;
** SSL certificate is expiring in &amp;lt; 24 hours: This is a bit dependent on how soon this incident is being handled, but if it handled quickly, the certificate never actually expired, and there has not been any disruption to the client&#039;s service, so no need for communicating about it.&lt;br /&gt;
* Determining which clients are being affected can be done by looking at the host&#039;s DNS in the trigger, and/or looking up the VM in Proxmox and checking the tags of the VM&#039;s for client names. In the case that this issue is causing multiple other critical triggers to fire, you would have to check for which clients are affected by those incidents.&lt;br /&gt;
* Communicating to DS about ongoing incidents is usually assumed to be automaticly have been done by the fact that the incident was reported on Zulip.&lt;br /&gt;
&lt;br /&gt;
As always, report the decisions taken and actions maded in the incident thread. (e.g.: I&#039;ve sent a message in the Slack to let Kaboom know that we aware of problem x, and that we are investigating it)&lt;br /&gt;
&lt;br /&gt;
==== Communicate plan/next steps + Communicate findings/results of executed plan ====&lt;br /&gt;
This is the main part of handling an incident. There are several actions you can take in these steps, but at the basis they consist of sharing your next steps, performing those, and reporting the results. The reason all this needs to be reported is to ensure that all known information about a problem is logged, making it easier for someone else to be onboarded into the issue, for later reference if a similar issue is encountered, and even for use during the incident itself in case an older configuration needs to be referenced after you changed it.&lt;br /&gt;
The objective from these steps is determining what is actually wrong and how to resolve it. Depending on the observations made earlier on whether the incident is still ongoing and is (still) observable your investigation can go into different directions. (e.g. Find the underlying cause for a trigger, or determining why the trigger is firing while it likely shouldn&#039;t, and then how to resolve that underlying cause or how to update the trigger to work better)&lt;br /&gt;
&lt;br /&gt;
There are three main types of steps defined, but you are not limited to these:&lt;br /&gt;
# Hypothesis: If you have an idea what could be causing it, you would state your hypothesis and your next step would be to prove that hypothesis. For example, for an incident &#039;SSH service is down on X&#039; your hypothesis could be that this is due to &#039;MaxStartups&#039; throttling, which can be proven by &#039;grep&#039;ing journalctl for that, and compare the start and end times of throttling with the timestamps of the item reporting the status of the SSH service.&lt;br /&gt;
# Information gathering: Sometimes it just helps to get some facts about the situation collected. What is usefull information that is relevant depends on the triggers, but some examples are: The syslog/journalctl of the host from around the time of the incident (it can contain a reference to the an underlying problem in various levels of explicitness), the ping response from several hosts on the route to a host or a traceroute (this helps with networking issues). The gathered information is usually intended to help you come up with an hypothesis on what&#039;s wrong.&lt;br /&gt;
# Investigative: The most rigorous of process. The full process is described here originally [https://docs.google.com/document/d/1AQYJM1Q9l2Tyk6zfCVaQ2aEq-dpbfUH5okE88bpKkhw/edit#heading=h.5fq2skijqbdc Drive - Final Coundown - General Investigative Process]. To summarize, when you don&#039;t know why something is failing, and/or don&#039;t have any decent hypotheses to follow up, you can follow this process to systematicly find the problem.&lt;br /&gt;
&lt;br /&gt;
Regarding the resolution to an incident: The resolution to any incident is usually one of two things:&lt;br /&gt;
# Fix the underlying problem.&lt;br /&gt;
# Fix the trigger itself.&lt;br /&gt;
Fixing the trigger is relavively straightforward, but do make sure document in the thread what you changed to which trigger.&lt;br /&gt;
Fixing the underlying problem can be more complex. A trade-off needs to be made sometimes between resolving technical debt, or simply patching the current system to resolve the issue. We usually look for a resolution that ensures that the problem won&#039;t re-occur soon, or makes it unexpected/unlikely for the problem to re-occur. Taking into account the timeframe that is available to resolve the incident you can make some trade-offs. An example would be: normal backups of VM&#039;s are failing due to the Proxmox backup server being down/unreachable and it is determined that this cannot be resolved at that moment. We can set up automatic backups to local storage temporary to resolve the immediate problem and ensure we keep our SLO&#039;s versus setting up a new Proxmox Backup server at a different location. Since we don&#039;t have much time to resolve the problem, the resolution would be to set up the automatic backups to local storage, and set up a new Proxmox Backup Server later as a seperate issue.&lt;br /&gt;
&lt;br /&gt;
Some know issues and their resolutions:&lt;br /&gt;
* SSH service is down: The internet is a vile place. There&#039;s constant port scanning and hacking attempts ongoing to any machine connected to the internet (mostly IPv4). Due to this, SSH has a throttling functionality build in to prevent a system from being DDOS&#039;ed by the amount of malicious SSH requests. This throttling can cause the Zabbix server from being denied an SSH connection, of which several failures fire this trigger. This hypothesis can be proven with a `journalctl -u ssh | grep &#039;MaxStartupsThrottling&#039;` (you probably want to select a relevant time period with `--since &amp;quot;2 hours ago&amp;quot;` or something similar to prevent having to process a month of logging). You can then compare the throttling start and end times with the timestamps of the item data itself. The resolution for the issue is to add our custom ssh configuration [https://chat.dsinternal.net/#narrow/stream/23-SRE---General/topic/DS.20Whitelisted.20Custom.20SSH.20configuration/near/1620 Custom SSH Configuration].&lt;br /&gt;
* No backup for 3 days: Are S3 backup is very slow. Not much to prove as an underlying issue here. What needs to be done is check that the backup process is ongoing. The Zabbix latest data can be checked to verify that backups are running by checking that that days backups were done for the smaller buckets. The devteam email can be checked for if the backup process could not start on day due to it already running (it takes 24+ hours, and an attempt to start it is done each day by cron).&lt;br /&gt;
* git.* HTTPS is down: On Sunday mostly, Gitlab gets automaticly updated, but this incurs some downtime as the service is restarted. This is usually short enough to not be reported to Zulip as per our settings, but sometimes it&#039;s longer. If the service does not stay down, the issue can be just resolved.&lt;br /&gt;
&lt;br /&gt;
==== Resolve incident + cleanup ====&lt;br /&gt;
When you&#039;ve executed and verified the resolution in the previous steps we can proceed resolving the issue in our Mattermost integration. Resolving an incident can be done by doing the following:&lt;br /&gt;
# Verify that the trigger is no longer firing. An incident will be immediatly re-opened if the trigger is still firing, and the incident cannot be considered resolved if the trigger is still firing. If the trigger is still firing but you&#039;re sure that you&#039;ve resolved the problem, you might need to force the item the trigger depends on to update. This can be done by finding the item in the host&#039;s configuration on Zabbix and selecting &#039;Execute Now&#039;, after a short period this should force Zabbix to re-execute the item. You can check the timestamps in the latest data of an item to check if it was updated.&lt;br /&gt;
# Close the incident by marking the topic as resolved, when there are no other triggers firing for the host.&lt;br /&gt;
&lt;br /&gt;
Unfortunatly, some problems cause multiple critical and non-critical triggers to fire. This means we have to check Zabbix and Zulip for other fired triggers and ongoing incidents. The goal is to identify critical and non-critical incidents that were caused by the incident/underlying issue you just resolved.&lt;br /&gt;
# First, these incidents need to be acknowledged on Zabbix, and in the acknowledgement message you mention the incident/problem that caused this.&lt;br /&gt;
# Next, check the incident tracked by the integration on Mattermost using the `?ongoing` command. Resolve incidents that were (re-)opened by this incident by executing the following steps. If the first two fail (problem still persists, trigger is still firing), the incident needs to considered it&#039;s own issue and the relevant process needs to be followed (critical or non-critical depending on criticality).&lt;br /&gt;
## Ensuring the mentioned problem is no longer observable&lt;br /&gt;
## The trigger has resolved (You might need to force an update with `Execute Now`).&lt;br /&gt;
## Posting a link to the main incident you resolved with the comment that the underlying problem was resolved in that topic.&lt;br /&gt;
## Closing the incident by marking the topic as resolved, when there are no other triggers firing for the host.&lt;br /&gt;
&lt;br /&gt;
When you are done, there should be no more critical triggers firing in Zabbix or open in the Zabbix-Mattermost intergration, for which no-one has taken responsibility or you have taken responsibility for and are not actively handling.&lt;br /&gt;
&lt;br /&gt;
===Additional context===&lt;br /&gt;
* Critical incidents are posted in [https://chat.dsinternal.net/#narrow/stream/24-SRE-.23-Critical &#039;&#039;&#039;SLA - Critical&#039;&#039;&#039;].&lt;br /&gt;
* &amp;lt;s&amp;gt;When it is being tracked on GitLab a heavy check mark is added to the message.&amp;lt;/s&amp;gt;&lt;br /&gt;
* &amp;lt;s&amp;gt;Responses on the thread and on GitLab are automatically synced (to some extend)&amp;lt;/s&amp;gt;&lt;br /&gt;
* &amp;lt;s&amp;gt;When you reply with &#039;&#039;&#039;I agree that this has been fully resolved&#039;&#039;&#039; eventually our Zabbix-Mattermost integration will pick this up and a green check mark is added to the message.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Non-Critical incidents ==&lt;br /&gt;
* Non-critical incidents are acknowledged within 9 hours and resolved within one week.&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix and state who is responsible for resolving this in the description&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# If there is no resolution to the incident, evaluate if the trigger needs updating/disabling&lt;br /&gt;
# Resolve incident&lt;br /&gt;
&lt;br /&gt;
== Informational incidents ==&lt;br /&gt;
* Informational incidents are acknowledged within 72 hours&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix&lt;br /&gt;
# Sanity check the event, post result in thread&lt;br /&gt;
# If action needed, perform action&lt;br /&gt;
&lt;br /&gt;
== If an incident is reported by other means than the Zabbix-Zulip intergration ==&lt;br /&gt;
# Acknowledge receipt.&lt;br /&gt;
# Classify the incident as critical, non-critical, or informational.&lt;br /&gt;
# Create an topic in the relevant SRE channel, stating the problem and that you is responsible for resolving it.&lt;br /&gt;
# Proceed to treat the incident according to the criticality you just classified it as. (So for a critical incident, it means you now start the critical incident handling process)&lt;br /&gt;
&lt;br /&gt;
== Handover ==&lt;br /&gt;
When handing over the responsibility of &#039;&#039;&#039;first responder&#039;&#039;&#039; (FR), the following needs to happen:&lt;br /&gt;
* Acting FR adds the upcoming FR the the IPA sla-first-responder user group (Optional: and enables Zabbix calling for that person if they have that set by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; [https://status.delftinfra.net/zabbix/actionconf.php?eventsource=0# Trigger actions])&lt;br /&gt;
* The upcoming FR makes sure they are aware of the state of the SLA and knows what questions they wants to ask the acting FR.&lt;br /&gt;
* The upcoming FR makes sure they are subscribed to the right channels&lt;br /&gt;
&lt;br /&gt;
The following steps can be done async or in person:&lt;br /&gt;
* The acting FR announces/informs the upcoming FR has been added to the sla-first-responder group (In Zulip&#039;s [https://chat.dsinternal.net/#narrow/stream/13-Organisational Organisational channel] if asynq).&lt;br /&gt;
* If the acting FR wants to hand over responsibility for any ongoing incident they also state which incidents they want the upcoming FR to take over.&lt;br /&gt;
* If there are any particularities the upcoming FR needs to be aware of, those are shared.&lt;br /&gt;
* The upcoming FR asks their questions until they are satisfied and able to take over the FR&lt;br /&gt;
* The upcoming FR ensures they are subscribed to the following channels on Zulip: [https://chat.dsinternal.net/#narrow/stream/23-SRE---General SRE - General], [https://chat.dsinternal.net/#narrow/stream/24-SRE-.23-Critical SRE # Critical] and if part of the SRE team [https://chat.dsinternal.net/#streams/4/SRE%20##%20Non-critical SRE ## Non-Critical] and [https://chat.dsinternal.net/#streams/5/SRE%20###%20Informational SRE ### Informational].&lt;br /&gt;
* The upcoming FR announces/informs that they are now the acting FR over Zulip&#039;s [https://chat.dsinternal.net/#narrow/stream/13-Organisational Organisational channel]&lt;br /&gt;
* The now acting FR removes the previous FR from IPA the sla-first-responder user group (Optional: and disables Zabbix calling for that person if they had that enabled by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; [https://status.delftinfra.net/zabbix/actionconf.php?eventsource=0# Trigger actions])&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=372</id>
		<title>Incident Handling</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=372"/>
		<updated>2024-07-05T17:17:46Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Additional context */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Zulip migration ==&lt;br /&gt;
Due to a migration to Zulip, the integration as was available on Mattermost is not available yet on Zulip. This leads to the following process changes:&lt;br /&gt;
* Acknowlegements and triggers resolving are not posted to Zulip by Zabbix&lt;br /&gt;
* Triggers are grouped in a topic on Zulip per host&lt;br /&gt;
* When an incident has been fully resolved, mark the topic as resolved, when any other incidents reported for the host are resolved&lt;br /&gt;
* There&#039;s no `?ongoing`, instead for now we can track open incidents by checking for unresolved topics&lt;br /&gt;
* The posting of incidents is less smart (only posting when not posted yet), so in order to prevent an incident from not being reported due to network issues or the likes, a message is posted after an inteval (8 hours for non-critical and lower, 1 hour for critical and above) while the incident has not been acknowleged.&lt;br /&gt;
* Incidents can be manually tracked by creating a topic by hand and reporting the problem&lt;br /&gt;
* There is no automatic gitlab issue creation or syncing anymore.&lt;br /&gt;
&lt;br /&gt;
Finally, where this process says to do something on Mattermost, you should now do so on Zulip. The updates in the process chapters themselves are WIP.&lt;br /&gt;
&lt;br /&gt;
== Critical incidents ==&lt;br /&gt;
* Critical incidents are resolved within 16 hours.&lt;br /&gt;
&lt;br /&gt;
As first responder you take on the responsiblity of seeing an incident resolved. This does not mean that you are the person required to do all the work. You can attempt to involve other to help you (often referred to as escalating the incident), but since other are not on-call, they are not obliged to help you, especially outside of normal working hours.&lt;br /&gt;
Involving multiple people can quickly be required if multiple critical incidents with different causes occur simultaniously. In that case, the First Responder usually takes on a more information management role and steers those that are brought on into resolving the issues. (Example: if a server crashes, several critical triggers can fire, but the underlying cause can quite quickly be determined to be a single issue, the crashed server. So you wouldn&#039;t need to call in people to manage each incident. But a client&#039;s service being down in one cluster while in a different cluster a different VM no longer boots is likely to be to different issues, so in order to resolve them on time you&#039;d want to call in help to resolve the incident in time).&lt;br /&gt;
&lt;br /&gt;
=== Process ===&lt;br /&gt;
The general process is made up of the folowing steps. Each step has additional information on how to handle/execute them in the sections below.&lt;br /&gt;
# Take responsibility for seeing the incident resolved&lt;br /&gt;
# Determine if incident is still ongoing&lt;br /&gt;
# If ongoing: Communicate to affected clients that the issue is being investigated&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# Resolve incident + cleanup&lt;br /&gt;
&lt;br /&gt;
During working on an incident it is expected that all communication is done in the incident&#039;s thread. This means all information to a problem can be found in a clear a predictable place. Sometimes an incident can be resolved by work done in another incident. In that case, it is required to post a link to that thread in the incident&#039;s thread with the comment that the resolution is done in that thread.&lt;br /&gt;
&lt;br /&gt;
==== Acknowledge the incident on Zabbix ====&lt;br /&gt;
The first step is to take responsibility for seeing the incident resolved by acknowledging the incident on Zabbix. Simply acknowledging the trigger suffices. It is however entirely possible that multiple critical incidents are firing at the same time. This can be a coincidence, or can be because of a share cause of failure. For example, a server crashing will cause server VM&#039; to reboot, or the router having an connectivity issue will lead to most other VM&#039;s having connectivity issues as well. If there are multiple critical incidents, it is advised to quickly observe what&#039;s ongoing, Zabbix is the best source of firing triggers for this, and pick the incident that is likely the root cause to  &lt;br /&gt;
&lt;br /&gt;
* Acknowledging an incident on Zabbix will stop Zabbix from calling the First Responder to notify them of the ongoing incident. And stops Zabbix from posting reminders on Zulip.&lt;br /&gt;
&lt;br /&gt;
==== Determine if incident is still ongoing ====&lt;br /&gt;
The next step is to check if the reported problem is still ongoing. Depending on the observations made here your process to follow and steps needed to resolve the incident can change. There are three options:&lt;br /&gt;
# The trigger resolved itself and the problem cannot be observed. Example: HTTPS is down for a site, but the FR can access the site through HTTPS without incident.&lt;br /&gt;
# The trigger resolved itself and the problem can still be observed.&lt;br /&gt;
# The trigger is still firing but the problem cannot be observed: Our triggers might not be perfect, so it could be that something else is causing it to fire. A simple example would be that Zabbix reports that the the DNS for a site can&#039;t be resolved, but in reality there&#039;s a bug in the script we wrote that checks if the DNS resolves and the DNS resolves fine. Final note: keep in mind that an &#039;it works on my machine&#039; does not necessarily mean it works for most other people, so depening on the trigger you need to do some evaluations if your tests suffice. &lt;br /&gt;
&lt;br /&gt;
In order to make sure you are actually trying to observe the same thing as the trigger is looking for, make sure to check the trigger definition and the current data of the associated item(s). Some triggers might fire if one of multiple conditions is met (Such as a trigger that monitors the ping response time firing if the value exceeds a certain threshold, or if no data for a certain period of time was observed).&lt;br /&gt;
&lt;br /&gt;
Make sure to report your findings in the incident&#039;s thread. It&#039;s advised to post a screenshot of the relevant item(s) and your own observations. (Continuing the ping example, you would post a screenshot of the relevant values, state your conclusion why the trigger is firing, and your own observations/pings)&lt;br /&gt;
&lt;br /&gt;
==== Communicate to affected clients ====&lt;br /&gt;
If the incident is still ongoing and the service is down, we need to communicate to affected clients that we are aware of the problem and that we are investigating it. This is because critical incident usually mean the service is down, something the clients can notice/are affected by, so we to be transparent that something is going on. There are some additional notes to this though:&lt;br /&gt;
* If an incident has already resolved itself and the problem is no longer observable, we don&#039;t communicate anything. Doing so might only cause confusion, and since the client has not reported any issues, they have not had a noticeable problem with it themselves.&lt;br /&gt;
* Although a critical incident generally means that the client service is down or experiencing reduced service, not all critical incidents are of that nature. Some are more administrative, or are only an issue for Delft Solutions itself. As of writing I don&#039;t have an exhaustive list, but here is those I can think of:&lt;br /&gt;
** SSH Service is down: We don&#039;t have any clients that SSH into their services, so it&#039;s generally not a problem. But SSH is mostly used for SRE maintenance and publishing new builds. The SRE maintenance is an internal problem, so no need to communicate to the client. The publishing is done to Kaboom, preventing new builds from being published, and the two SM VM&#039;s.&lt;br /&gt;
** No backup for x days: Clients don&#039;t notice it if a backup is running late, so no need to communicate with clients. Just need to make sure the backup gets completed&lt;br /&gt;
** SSL certificate is expiring in &amp;lt; 24 hours: This is a bit dependent on how soon this incident is being handled, but if it handled quickly, the certificate never actually expired, and there has not been any disruption to the client&#039;s service, so no need for communicating about it.&lt;br /&gt;
* Determining which clients are being affected can be done by looking at the host&#039;s DNS in the trigger, and/or looking up the VM in Proxmox and checking the tags of the VM&#039;s for client names. In the case that this issue is causing multiple other critical triggers to fire, you would have to check for which clients are affected by those incidents.&lt;br /&gt;
* Communicating to DS about ongoing incidents is usually assumed to be automaticly have been done by the fact that the incident was reported on Zulip.&lt;br /&gt;
&lt;br /&gt;
As always, report the decisions taken and actions maded in the incident thread. (e.g.: I&#039;ve sent a message in the Slack to let Kaboom know that we aware of problem x, and that we are investigating it)&lt;br /&gt;
&lt;br /&gt;
==== Communicate plan/next steps + Communicate findings/results of executed plan ====&lt;br /&gt;
This is the main part of handling an incident. There are several actions you can take in these steps, but at the basis they consist of sharing your next steps, performing those, and reporting the results. The reason all this needs to be reported is to ensure that all known information about a problem is logged, making it easier for someone else to be onboarded into the issue, for later reference if a similar issue is encountered, and even for use during the incident itself in case an older configuration needs to be referenced after you changed it.&lt;br /&gt;
The objective from these steps is determining what is actually wrong and how to resolve it. Depending on the observations made earlier on whether the incident is still ongoing and is (still) observable your investigation can go into different directions. (e.g. Find the underlying cause for a trigger, or determining why the trigger is firing while it likely shouldn&#039;t, and then how to resolve that underlying cause or how to update the trigger to work better)&lt;br /&gt;
&lt;br /&gt;
There are three main types of steps defined, but you are not limited to these:&lt;br /&gt;
# Hypothesis: If you have an idea what could be causing it, you would state your hypothesis and your next step would be to prove that hypothesis. For example, for an incident &#039;SSH service is down on X&#039; your hypothesis could be that this is due to &#039;MaxStartups&#039; throttling, which can be proven by &#039;grep&#039;ing journalctl for that, and compare the start and end times of throttling with the timestamps of the item reporting the status of the SSH service.&lt;br /&gt;
# Information gathering: Sometimes it just helps to get some facts about the situation collected. What is usefull information that is relevant depends on the triggers, but some examples are: The syslog/journalctl of the host from around the time of the incident (it can contain a reference to the an underlying problem in various levels of explicitness), the ping response from several hosts on the route to a host or a traceroute (this helps with networking issues). The gathered information is usually intended to help you come up with an hypothesis on what&#039;s wrong.&lt;br /&gt;
# Investigative: The most rigorous of process. The full process is described here originally [https://docs.google.com/document/d/1AQYJM1Q9l2Tyk6zfCVaQ2aEq-dpbfUH5okE88bpKkhw/edit#heading=h.5fq2skijqbdc Drive - Final Coundown - General Investigative Process]. To summarize, when you don&#039;t know why something is failing, and/or don&#039;t have any decent hypotheses to follow up, you can follow this process to systematicly find the problem.&lt;br /&gt;
&lt;br /&gt;
Regarding the resolution to an incident: The resolution to any incident is usually one of two things:&lt;br /&gt;
# Fix the underlying problem.&lt;br /&gt;
# Fix the trigger itself.&lt;br /&gt;
Fixing the trigger is relavively straightforward, but do make sure document in the thread what you changed to which trigger.&lt;br /&gt;
Fixing the underlying problem can be more complex. A trade-off needs to be made sometimes between resolving technical debt, or simply patching the current system to resolve the issue. We usually look for a resolution that ensures that the problem won&#039;t re-occur soon, or makes it unexpected/unlikely for the problem to re-occur. Taking into account the timeframe that is available to resolve the incident you can make some trade-offs. An example would be: normal backups of VM&#039;s are failing due to the Proxmox backup server being down/unreachable and it is determined that this cannot be resolved at that moment. We can set up automatic backups to local storage temporary to resolve the immediate problem and ensure we keep our SLO&#039;s versus setting up a new Proxmox Backup server at a different location. Since we don&#039;t have much time to resolve the problem, the resolution would be to set up the automatic backups to local storage, and set up a new Proxmox Backup Server later as a seperate issue.&lt;br /&gt;
&lt;br /&gt;
Some know issues and their resolutions:&lt;br /&gt;
* SSH service is down: The internet is a vile place. There&#039;s constant port scanning and hacking attempts ongoing to any machine connected to the internet (mostly IPv4). Due to this, SSH has a throttling functionality build in to prevent a system from being DDOS&#039;ed by the amount of malicious SSH requests. This throttling can cause the Zabbix server from being denied an SSH connection, of which several failures fire this trigger. This hypothesis can be proven with a `journalctl -u ssh | grep &#039;MaxStartupsThrottling&#039;` (you probably want to select a relevant time period with `--since &amp;quot;2 hours ago&amp;quot;` or something similar to prevent having to process a month of logging). You can then compare the throttling start and end times with the timestamps of the item data itself. The resolution for the issue is to add our custom ssh configuration [https://chat.dsinternal.net/#narrow/stream/23-SRE---General/topic/DS.20Whitelisted.20Custom.20SSH.20configuration/near/1620 Custom SSH Configuration].&lt;br /&gt;
* No backup for 3 days: Are S3 backup is very slow. Not much to prove as an underlying issue here. What needs to be done is check that the backup process is ongoing. The Zabbix latest data can be checked to verify that backups are running by checking that that days backups were done for the smaller buckets. The devteam email can be checked for if the backup process could not start on day due to it already running (it takes 24+ hours, and an attempt to start it is done each day by cron).&lt;br /&gt;
* git.* HTTPS is down: On Sunday mostly, Gitlab gets automaticly updated, but this incurs some downtime as the service is restarted. This is usually short enough to not be reported to Zulip as per our settings, but sometimes it&#039;s longer. If the service does not stay down, the issue can be just resolved.&lt;br /&gt;
&lt;br /&gt;
==== Resolve incident + cleanup ====&lt;br /&gt;
When you&#039;ve executed and verified the resolution in the previous steps we can proceed resolving the issue in our Mattermost integration. Resolving an incident can be done by doing the following:&lt;br /&gt;
# Verify that the trigger is no longer firing. An incident will be immediatly re-opened if the trigger is still firing, and the incident cannot be considered resolved if the trigger is still firing. If the trigger is still firing but you&#039;re sure that you&#039;ve resolved the problem, you might need to force the item the trigger depends on to update. This can be done by finding the item in the host&#039;s configuration on Zabbix and selecting &#039;Execute Now&#039;, after a short period this should force Zabbix to re-execute the item. You can check the timestamps in the latest data of an item to check if it was updated.&lt;br /&gt;
# Close the incident by marking the topic as resolved, when there are no other triggers firing for the host.&lt;br /&gt;
&lt;br /&gt;
Unfortunatly, some problems cause multiple critical and non-critical triggers to fire. This means we have to check Zabbix and Zulip for other fired triggers and ongoing incidents. The goal is to identify critical and non-critical incidents that were caused by the incident/underlying issue you just resolved.&lt;br /&gt;
# First, these incidents need to be acknowledged on Zabbix, and in the acknowledgement message you mention the incident/problem that caused this.&lt;br /&gt;
# Next, check the incident tracked by the integration on Mattermost using the `?ongoing` command. Resolve incidents that were (re-)opened by this incident by executing the following steps. If the first two fail (problem still persists, trigger is still firing), the incident needs to considered it&#039;s own issue and the relevant process needs to be followed (critical or non-critical depending on criticality).&lt;br /&gt;
## Ensuring the mentioned problem is no longer observable&lt;br /&gt;
## The trigger has resolved (You might need to force an update with `Execute Now`).&lt;br /&gt;
## Posting a link to the main incident you resolved with the comment that the underlying problem was resolved in that topic.&lt;br /&gt;
## Closing the incident by marking the topic as resolved, when there are no other triggers firing for the host.&lt;br /&gt;
&lt;br /&gt;
When you are done, there should be no more critical triggers firing in Zabbix or open in the Zabbix-Mattermost intergration, for which no-one has taken responsibility or you have taken responsibility for and are not actively handling.&lt;br /&gt;
&lt;br /&gt;
===Additional context===&lt;br /&gt;
* Critical incidents are posted in [https://chat.dsinternal.net/#narrow/stream/24-SRE-.23-Critical &#039;&#039;&#039;SLA - Critical&#039;&#039;&#039;].&lt;br /&gt;
* &amp;lt;s&amp;gt;When it is being tracked on GitLab a heavy check mark is added to the message.&amp;lt;/s&amp;gt;&lt;br /&gt;
* &amp;lt;s&amp;gt;Responses on the thread and on GitLab are automatically synced (to some extend)&amp;lt;/s&amp;gt;&lt;br /&gt;
* &amp;lt;s&amp;gt;When you reply with &#039;&#039;&#039;I agree that this has been fully resolved&#039;&#039;&#039; eventually our Zabbix-Mattermost integration will pick this up and a green check mark is added to the message.&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Non-Critical incidents ==&lt;br /&gt;
* Non-critical incidents are acknowledged within 9 hours and resolved within one week.&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix and state who is responsible for resolving this in the description&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# If there is no resolution to the incident, evaluate if the trigger needs updating/disabling&lt;br /&gt;
# Resolve incident&lt;br /&gt;
&lt;br /&gt;
== Informational incidents ==&lt;br /&gt;
* Informational incidents are acknowledged within 72 hours&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix&lt;br /&gt;
# Sanity check the event, post result in thread&lt;br /&gt;
# If action needed, perform action&lt;br /&gt;
&lt;br /&gt;
== If an incident is reported by other means than the Zabbix-Zulip intergration ==&lt;br /&gt;
# Acknowledge receipt.&lt;br /&gt;
# Classify the incident as critical, non-critical, or informational.&lt;br /&gt;
# Create an topic in the relevant SRE channel, stating the problem and that you is responsible for resolving it.&lt;br /&gt;
# Proceed to treat the incident according to the criticality you just classified it as. (So for a critical incident, it means you now start the critical incident handling process)&lt;br /&gt;
&lt;br /&gt;
== Handover ==&lt;br /&gt;
When handing over the responsibility of first responder (FR), the following needs to happen:&lt;br /&gt;
* Acting FR adds the upcoming FR the the IPA sla-first-responder user group (Optional: and enables Zabbix calling for that person if they have that set by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; Trigger actions)&lt;br /&gt;
* The upcoming FR makes sure they are aware of the state of the SLA and knows what questions they wants to ask the acting FR.&lt;br /&gt;
The following steps can be done async or in person:&lt;br /&gt;
* The acting FR announces/informs the upcoming FR has been added to the sla-first-responder group (In Zulip&#039;s organisational channel if asynq).&lt;br /&gt;
* If the acting FR wants to hand over responsibility for any ongoing incident they also state which incidents they want the upcoming FR to take over.&lt;br /&gt;
* If there are any particularities the upcoming FR needs to be aware of, those are shared.&lt;br /&gt;
* The upcoming FR asks their questions until they are satisfied and able to take over the FR&lt;br /&gt;
* The upcoming FR announces/informs that they are now the acting FR over Zulip&#039;s organisational channel&lt;br /&gt;
* The now acting FR removes the previous FR from IPA the sla-first-responder user group (Optional: and disables Zabbix calling for that person if they had that enabled by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; Trigger actions)&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Stack&amp;diff=320</id>
		<title>Stack</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Stack&amp;diff=320"/>
		<updated>2024-05-28T17:22:46Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We tend to use &amp;quot;whatever tool for the job makes most sense&amp;quot; for greenfield projects.&lt;br /&gt;
&lt;br /&gt;
== Mobile applications ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Programming Languages&lt;br /&gt;
* Bash&lt;br /&gt;
* CSS&lt;br /&gt;
* HTML&lt;br /&gt;
* Kotlin&lt;br /&gt;
* Swift&lt;br /&gt;
* TypeScript&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Common Libraries&lt;br /&gt;
* [https://atlassian.design/components/pragmatic-drag-and-drop/core-package Pragmatic Drag and Drop]&lt;br /&gt;
* [https://reactnative.dev/ React-Native]&lt;br /&gt;
* [https://docs.swmansion.com/react-native-reanimated/ React-Native Reanimated]&lt;br /&gt;
* [https://tanstack.com/query/latest TanStack Query]&lt;br /&gt;
* [https://tanstack.com/table/latest TanStack Table]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;UI frameworks&lt;br /&gt;
* [https://www.nativewind.dev/ Nativewind]&lt;br /&gt;
* [https://reactnativepaper.com/ React-Native paper]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Frameworks&lt;br /&gt;
* [https://expo.dev/ Expo]&lt;br /&gt;
&lt;br /&gt;
== Full stack applications ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Programming Languages&lt;br /&gt;
* Bash&lt;br /&gt;
* CSS&lt;br /&gt;
* HTML&lt;br /&gt;
* Ruby&lt;br /&gt;
* TypeScript&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Common Libraries&lt;br /&gt;
* [https://github.com/SleeplessByte/media-types-ruby Media Types]&lt;br /&gt;
* [https://github.com/XPBytes/media_types-serialization/tree/master Media Types Serialization]&lt;br /&gt;
* [https://postcss.org/ PostCSS]&lt;br /&gt;
* [https://stimulus.hotwired.dev/ Stimulus]&lt;br /&gt;
* [https://uppy.io/docs/uppy/ Uppy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;UI frameworks&lt;br /&gt;
* [https://m3.material.io/ Material Design]&lt;br /&gt;
* [https://tailwindcss.com/ Tailwind CSS]&lt;br /&gt;
* [https://tailwindui.com/ Tailwind UI]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Frameworks&lt;br /&gt;
* [https://rubyonrails.org/ Ruby on Rails]&lt;br /&gt;
&lt;br /&gt;
== Front-endish web applications ==&lt;br /&gt;
&#039;&#039;Programming Languages&lt;br /&gt;
* Bash&lt;br /&gt;
* CSS&lt;br /&gt;
* HTML&lt;br /&gt;
* TypeScript&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Libraries&lt;br /&gt;
* [https://react.dev React]&lt;br /&gt;
* [https://tanstack.com/query/latest TanStack Query]&lt;br /&gt;
* [https://tanstack.com/table/latest TanStack Table]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;UI frameworks&lt;br /&gt;
* [https://m3.material.io/ Material Design]&lt;br /&gt;
* [https://tailwindcss.com/ Tailwind CSS]&lt;br /&gt;
* [https://tailwindui.com/ Tailwind UI]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Frameworks&lt;br /&gt;
* [https://remix.run/ Remix]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Stack&amp;diff=319</id>
		<title>Stack</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Stack&amp;diff=319"/>
		<updated>2024-05-28T17:22:23Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;We tend to use &amp;quot;whatever tool for the job makes most sense&amp;quot; for greenfield projects.  == Mobile applications ==  &amp;#039;&amp;#039;Programming Languages * Bash * CSS * HTML * Kotlin * Swift * TypeScript  &amp;#039;&amp;#039;Common Libraries * [https://atlassian.design/components/pragmatic-drag-and-drop/core-package Pragmatic Drag and Drop] * [https://reactnative.dev/ React-Native] * [https://docs.swmansion.com/react-native-reanimated/ React-Native Reanimated] * [https://tanstack.com/query/latest TanStack...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We tend to use &amp;quot;whatever tool for the job makes most sense&amp;quot; for greenfield projects.&lt;br /&gt;
&lt;br /&gt;
== Mobile applications ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Programming Languages&lt;br /&gt;
* Bash&lt;br /&gt;
* CSS&lt;br /&gt;
* HTML&lt;br /&gt;
* Kotlin&lt;br /&gt;
* Swift&lt;br /&gt;
* TypeScript&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Common Libraries&lt;br /&gt;
* [https://atlassian.design/components/pragmatic-drag-and-drop/core-package Pragmatic Drag and Drop]&lt;br /&gt;
* [https://reactnative.dev/ React-Native]&lt;br /&gt;
* [https://docs.swmansion.com/react-native-reanimated/ React-Native Reanimated]&lt;br /&gt;
* [https://tanstack.com/query/latest TanStack Query]&lt;br /&gt;
* [https://tanstack.com/table/latest TanStack Table]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;UI frameworks&lt;br /&gt;
* [https://www.nativewind.dev/ Nativewind]&lt;br /&gt;
* [https://reactnativepaper.com/ React-Native paper]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Frameworks&lt;br /&gt;
* [https://expo.dev/ Expo]&lt;br /&gt;
&lt;br /&gt;
== Full stack applications ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Programming Languages&lt;br /&gt;
* Bash&lt;br /&gt;
* CSS&lt;br /&gt;
* HTML&lt;br /&gt;
* Ruby&lt;br /&gt;
* TypeScript&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Common Libraries&lt;br /&gt;
* [https://github.com/SleeplessByte/media-types-ruby Media Types]&lt;br /&gt;
* [https://github.com/XPBytes/media_types-serialization/tree/master Media Types Serialization]&lt;br /&gt;
* [https://postcss.org/ PostCSS]&lt;br /&gt;
* [https://stimulus.hotwired.dev/ Stimulus]&lt;br /&gt;
* [https://uppy.io/docs/uppy/ Uppy]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;UI frameworks&lt;br /&gt;
* [https://m3.material.io/ Material Design]&lt;br /&gt;
* [https://tailwindcss.com/ Tailwind CSS]&lt;br /&gt;
* [https://tailwindui.com/ Tailwind UI]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Frameworks&lt;br /&gt;
* [https://rubyonrails.org/ Ruby on Rails]&lt;br /&gt;
&lt;br /&gt;
== Front-endish web applications ==&lt;br /&gt;
* Bash&lt;br /&gt;
* CSS&lt;br /&gt;
* HTML&lt;br /&gt;
* TypeScript&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Libraries&lt;br /&gt;
* [https://react.dev React]&lt;br /&gt;
* [https://tanstack.com/query/latest TanStack Query]&lt;br /&gt;
* [https://tanstack.com/table/latest TanStack Table]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;UI frameworks&lt;br /&gt;
* [https://m3.material.io/ Material Design]&lt;br /&gt;
* [https://tailwindcss.com/ Tailwind CSS]&lt;br /&gt;
* [https://tailwindui.com/ Tailwind UI]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Frameworks&lt;br /&gt;
* [https://remix.run/ Remix]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=306</id>
		<title>Internal</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=306"/>
		<updated>2024-05-28T17:02:36Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Other */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Finance ==&lt;br /&gt;
&lt;br /&gt;
=== Exact ===&lt;br /&gt;
&lt;br /&gt;
* [[booking bonus|Booking bonus]]&lt;br /&gt;
* [[booking wages|Booking wages]]&lt;br /&gt;
* [[new receipt|Enter a new receipt]]&lt;br /&gt;
* [[reconciliation|Reconciliation of transaction]]&lt;br /&gt;
* [[invoicing|Send an invoice]]&lt;br /&gt;
* [[payment reminders|Send payment reminder]]&lt;br /&gt;
* [[invoice approval|Process for approving invoices (/filed receipts)]]&lt;br /&gt;
&lt;br /&gt;
=== Bunq ===&lt;br /&gt;
&lt;br /&gt;
* [[top up account|Top up expense account]]&lt;br /&gt;
&lt;br /&gt;
== Work Process ==&lt;br /&gt;
&lt;br /&gt;
* [[Definition of done|Definition of Done]]&lt;br /&gt;
* [[Incident Handling|Incident Handling]]&lt;br /&gt;
&lt;br /&gt;
== Internal Process ==&lt;br /&gt;
&lt;br /&gt;
* [[12 percent|12% time]]&lt;br /&gt;
* [[Annual leave|Annual leave]]&lt;br /&gt;
* [[Bonus allocation|Bonus allocation]]&lt;br /&gt;
* [[Calamity leave|Calamity leave]]&lt;br /&gt;
* [[Overtime|Overtime]]&lt;br /&gt;
* [[Retrospectives|Retrospectives]]&lt;br /&gt;
* [[Sick leave|Sick leave]]&lt;br /&gt;
* [[Training and self-study|Training and Self-Study]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
* Era Inventory [[project_era_inventory_api|API Description]]&lt;br /&gt;
&lt;br /&gt;
== SRE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To be further populated with guide from drive&#039;&#039;&lt;br /&gt;
* [[create gitlab runner host|Create a GitLab runner host]]&lt;br /&gt;
* [[vm setup|Create a (Debian) VM]]&lt;br /&gt;
* [[border reboot|Reboot border without downtime]]&lt;br /&gt;
* [[WS Proxmox node reboot|Reboot WS Proxmox node without downtime]]&lt;br /&gt;
* [[Resize VM Disk]]&lt;br /&gt;
* [[SRE tools]]&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
* [[stack|Greenfield stack]]&lt;br /&gt;
* [[standard tools|Standard Tools]]&lt;br /&gt;
* [[list of unfurl debuggers|List of unfurl debuggers]]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=SRE_tools&amp;diff=299</id>
		<title>SRE tools</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=SRE_tools&amp;diff=299"/>
		<updated>2024-05-28T16:57:33Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;* Ceph * Debian * FreeIPA * HTTPS/TLS * Kerberos * Keycloak * LDAP * MAKE * Netbox * Proxmox * Zabbix * Zulip  &amp;#039;&amp;#039;&amp;#039; Handbooks * [https://www.debian.org/doc/manuals/maint-guide/ Debian maintainers handbook] * Debian users handbook&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Ceph&lt;br /&gt;
* Debian&lt;br /&gt;
* FreeIPA&lt;br /&gt;
* HTTPS/TLS&lt;br /&gt;
* Kerberos&lt;br /&gt;
* Keycloak&lt;br /&gt;
* LDAP&lt;br /&gt;
* MAKE&lt;br /&gt;
* Netbox&lt;br /&gt;
* Proxmox&lt;br /&gt;
* Zabbix&lt;br /&gt;
* Zulip&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; Handbooks&lt;br /&gt;
* [https://www.debian.org/doc/manuals/maint-guide/ Debian maintainers handbook]&lt;br /&gt;
* Debian users handbook&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=298</id>
		<title>Internal</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=298"/>
		<updated>2024-05-28T16:53:16Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* SRE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Finance ==&lt;br /&gt;
&lt;br /&gt;
=== Exact ===&lt;br /&gt;
&lt;br /&gt;
* [[booking bonus|Booking bonus]]&lt;br /&gt;
* [[booking wages|Booking wages]]&lt;br /&gt;
* [[new receipt|Enter a new receipt]]&lt;br /&gt;
* [[reconciliation|Reconciliation of transaction]]&lt;br /&gt;
* [[invoicing|Send an invoice]]&lt;br /&gt;
* [[payment reminders|Send payment reminder]]&lt;br /&gt;
* [[invoice approval|Process for approving invoices (/filed receipts)]]&lt;br /&gt;
&lt;br /&gt;
=== Bunq ===&lt;br /&gt;
&lt;br /&gt;
* [[top up account|Top up expense account]]&lt;br /&gt;
&lt;br /&gt;
== Work Process ==&lt;br /&gt;
&lt;br /&gt;
* [[Definition of done|Definition of Done]]&lt;br /&gt;
* [[Incident Handling|Incident Handling]]&lt;br /&gt;
&lt;br /&gt;
== Internal Process ==&lt;br /&gt;
&lt;br /&gt;
* [[12 percent|12% time]]&lt;br /&gt;
* [[Annual leave|Annual leave]]&lt;br /&gt;
* [[Bonus allocation|Bonus allocation]]&lt;br /&gt;
* [[Calamity leave|Calamity leave]]&lt;br /&gt;
* [[Overtime|Overtime]]&lt;br /&gt;
* [[Retrospectives|Retrospectives]]&lt;br /&gt;
* [[Sick leave|Sick leave]]&lt;br /&gt;
* [[Training and self-study|Training and Self-Study]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
* Era Inventory [[project_era_inventory_api|API Description]]&lt;br /&gt;
&lt;br /&gt;
== SRE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To be further populated with guide from drive&#039;&#039;&lt;br /&gt;
* [[create gitlab runner host|Create a GitLab runner host]]&lt;br /&gt;
* [[vm setup|Create a (Debian) VM]]&lt;br /&gt;
* [[border reboot|Reboot border without downtime]]&lt;br /&gt;
* [[WS Proxmox node reboot|Reboot WS Proxmox node without downtime]]&lt;br /&gt;
* [[Resize VM Disk]]&lt;br /&gt;
* [[SRE tools]]&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
* [[standard tools|Standard Tools]]&lt;br /&gt;
* [[list of unfurl debuggers|List of unfurl debuggers]]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=297</id>
		<title>Incident Handling</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=297"/>
		<updated>2024-05-27T16:27:02Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Handover */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Critical incidents ==&lt;br /&gt;
* Critical incidents are resolved within 16 hours.&lt;br /&gt;
&lt;br /&gt;
As first responder you take on the responsiblity of seeing an incident resolved. This does not mean that you are the person required to do all the work. You can attempt to involve other to help you (often referred to as escalating the incident), but since other are not on-call, they are not obliged to help you, especially outside of normal working hours.&lt;br /&gt;
Involving multiple people can quickly be required if multiple critical incidents with different causes occur simultaniously. In that case, the First Responder usually takes on a more information management role and steers those that are brought on into resolving the issues. (Example: if a server crashes, several critical triggers can fire, but the underlying cause can quite quickly be determined to be a single issue, the crashed server. So you wouldn&#039;t need to call in people to manage each incident. But a client&#039;s service being down in one cluster while in a different cluster a different VM no longer boots is likely to be to different issues, so in order to resolve them on time you&#039;d want to call in help to resolve the incident in time).&lt;br /&gt;
&lt;br /&gt;
=== Process ===&lt;br /&gt;
The general process is made up of the folowing steps. Each step has additional information on how to handle/execute them in the sections below.&lt;br /&gt;
# Take responsibility for seeing the incident resolved&lt;br /&gt;
# Determine if incident is still ongoing&lt;br /&gt;
# If ongoing: Communicate to affected clients that the issue is being investigated&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# Resolve incident + cleanup&lt;br /&gt;
&lt;br /&gt;
During working on an incident it is expected that all communication is done in the incident&#039;s thread. This means all information to a problem can be found in a clear a predictable place. Sometimes an incident can be resolved by work done in another incident. In that case, it is required to post a link to that thread in the incident&#039;s thread with the comment that the resolution is done in that thread.&lt;br /&gt;
&lt;br /&gt;
==== Acknowledge the incident on Zabbix ====&lt;br /&gt;
The first step is to take responsibility for seeing the incident resolved by acknowledging the incident on Zabbix. Simply acknowledging the trigger suffices. It is however entirely possible that multiple critical incidents are firing at the same time. This can be a coincidence, or can be because of a share cause of failure. For example, a server crashing will cause server VM&#039; to reboot, or the router having an connectivity issue will lead to most other VM&#039;s having connectivity issues as well. If there are multiple critical incidents, it is advised to quickly observe what&#039;s ongoing, Zabbix is the best source of firing triggers for this, and pick the incident that is likely the root cause to  &lt;br /&gt;
&lt;br /&gt;
* Acknowledging an incident on Zabbix will stop Zabbix from calling the First Responder to notify them of the ongoing incident.&lt;br /&gt;
&lt;br /&gt;
==== Determine if incident is still ongoing ====&lt;br /&gt;
The next step is to check if the reported problem is still ongoing. Depending on the observations made here your process to follow and steps needed to resolve the incident can change. There are three options:&lt;br /&gt;
# The trigger resolved itself and the problem cannot be observed. Example: HTTPS is down for a site, but the FR can access the site through HTTPS without incident.&lt;br /&gt;
# The trigger resolved itself and the problem can still be observed.&lt;br /&gt;
# The trigger is still firing but the problem cannot be observed: Our triggers might not be perfect, so it could be that something else is causing it to fire. A simple example would be that Zabbix reports that the the DNS for a site can&#039;t be resolved, but in reality there&#039;s a bug in the script we wrote that checks if the DNS resolves and the DNS resolves fine. Final note: keep in mind that an &#039;it works on my machine&#039; does not necessarily mean it works for most other people, so depening on the trigger you need to do some evaluations if your tests suffice. &lt;br /&gt;
&lt;br /&gt;
In order to make sure you are actually trying to observe the same thing as the trigger is looking for, make sure to check the trigger definition and the current data of the associated item(s). Some triggers might fire if one of multiple conditions is met (Such as a trigger that monitors the ping response time firing if the value exceeds a certain threshold, or if no data for a certain period of time was observed).&lt;br /&gt;
&lt;br /&gt;
Make sure to report your findings in the incident&#039;s thread. It&#039;s advised to post a screenshot of the relevant item(s) and your own observations. (Continuing the ping example, you would post a screenshot of the relevant values, state your conclusion why the trigger is firing, and your own observations/pings)&lt;br /&gt;
&lt;br /&gt;
==== Communicate to affected clients ====&lt;br /&gt;
If the incident is still ongoing and the service is down, we need to communicate to affected clients that we are aware of the problem and that we are investigating it. This is because critical incident usually mean the service is down, something the clients can notice/are affected by, so we to be transparent that something is going on. There are some additional notes to this though:&lt;br /&gt;
* If an incident has already resolved itself and the problem is no longer observable, we don&#039;t communicate anything. Doing so might only cause confusion, and since the client has not reported any issues, they have not had a noticeable problem with it themselves.&lt;br /&gt;
* Although a critical incident generally means that the client service is down or experiencing reduced service, not all critical incidents are of that nature. Some are more administrative, or are only an issue for Delft Solutions itself. As of writing I don&#039;t have an exhaustive list, but here is those I can think of:&lt;br /&gt;
** SSH Service is down: We don&#039;t have any clients that SSH into their services, so it&#039;s generally not a problem. But SSH is mostly used for SRE maintenance and publishing new builds. The SRE maintenance is an internal problem, so no need to communicate to the client. The publishing is done to Kaboom, preventing new builds from being published, and the two SM VM&#039;s.&lt;br /&gt;
** No backup for x days: Clients don&#039;t notice it if a backup is running late, so no need to communicate with clients. Just need to make sure the backup gets completed&lt;br /&gt;
** SSL certificate is expiring in &amp;lt; 24 hours: This is a bit dependent on how soon this incident is being handled, but if it handled quickly, the certificate never actually expired, and there has not been any disruption to the client&#039;s service, so no need for communicating about it.&lt;br /&gt;
* Determining which clients are being affected can be done by looking at the host&#039;s DNS in the trigger, and/or looking up the VM in Proxmox and checking the tags of the VM&#039;s for client names. In the case that this issue is causing multiple other critical triggers to fire, you would have to check for which clients are affected by those incidents.&lt;br /&gt;
* Communicating to DS about ongoing incidents is usually assumed to be automaticly have been done by the fact that the incident was reported on Mattermost.&lt;br /&gt;
&lt;br /&gt;
As always, report the decisions taken and actions maded in the incident thread. (e.g.: I&#039;ve sent a message in the Slack to let Kaboom know that we aware of problem x, and that we are investigating it)&lt;br /&gt;
&lt;br /&gt;
==== Communicate plan/next steps + Communicate findings/results of executed plan ====&lt;br /&gt;
This is the main part of handling an incident. There are several actions you can take in these steps, but at the basis they consist of sharing your next steps, performing those, and reporting the results. The reason all this needs to be reported is to ensure that all known information about a problem is logged, making it easier for someone else to be onboarded into the issue, for later reference if a similar issue is encountered, and even for use during the incident itself in case an older configuration needs to be referenced after you changed it.&lt;br /&gt;
The objective from these steps is determining what is actually wrong and how to resolve it. Depending on the observations made earlier on whether the incident is still ongoing and is (still) observable your investigation can go into different directions. (e.g. Find the underlying cause for a trigger, or determining why the trigger is firing while it likely shouldn&#039;t, and then how to resolve that underlying cause or how to update the trigger to work better)&lt;br /&gt;
&lt;br /&gt;
There are three main types of steps defined, but you are not limited to these:&lt;br /&gt;
# Hypothesis: If you have an idea what could be causing it, you would state your hypothesis and your next step would be to prove that hypothesis. For example, for an incident &#039;SSH service is down on X&#039; your hypothesis could be that this is due to &#039;MaxStartups&#039; throttling, which can be proven by &#039;grep&#039;ing journalctl for that, and compare the start and end times of throttling with the timestamps of the item reporting the status of the SSH service.&lt;br /&gt;
# Information gathering: Sometimes it just helps to get some facts about the situation collected. What is usefull information that is relevant depends on the triggers, but some examples are: The syslog/journalctl of the host from around the time of the incident (it can contain a reference to the an underlying problem in various levels of explicitness), the ping response from several hosts on the route to a host or a traceroute (this helps with networking issues). The gathered information is usually intended to help you come up with an hypothesis on what&#039;s wrong.&lt;br /&gt;
# Investigative: The most rigorous of process. The full process is described here originally [https://docs.google.com/document/d/1AQYJM1Q9l2Tyk6zfCVaQ2aEq-dpbfUH5okE88bpKkhw/edit#heading=h.5fq2skijqbdc Drive - Final Coundown - General Investigative Process]. To summarize, when you don&#039;t know why something is failing, and/or don&#039;t have any decent hypotheses to follow up, you can follow this process to systematicly find the problem.&lt;br /&gt;
&lt;br /&gt;
Regarding the resolution to an incident: The resolution to any incident is usually one of two things:&lt;br /&gt;
# Fix the underlying problem.&lt;br /&gt;
# Fix the trigger itself.&lt;br /&gt;
Fixing the trigger is relavively straightforward, but do make sure document in the thread what you changed to which trigger.&lt;br /&gt;
Fixing the underlying problem can be more complex. A trade-off needs to be made sometimes between resolving technical debt, or simply patching the current system to resolve the issue. We usually look for a resolution that ensures that the problem won&#039;t re-occur soon, or makes it unexpected/unlikely for the problem to re-occur. Taking into account the timeframe that is available to resolve the incident you can make some trade-offs. An example would be: normal backups of VM&#039;s are failing due to the Proxmox backup server being down/unreachable and it is determined that this cannot be resolved at that moment. We can set up automatic backups to local storage temporary to resolve the immediate problem and ensure we keep our SLO&#039;s versus setting up a new Proxmox Backup server at a different location. Since we don&#039;t have much time to resolve the problem, the resolution would be to set up the automatic backups to local storage, and set up a new Proxmox Backup Server later as a seperate issue.&lt;br /&gt;
&lt;br /&gt;
Some know issues and their resolutions:&lt;br /&gt;
* SSH service is down: The internet is a vile place. There&#039;s constant port scanning and hacking attempts ongoing to any machine connected to the internet (mostly IPv4). Due to this, SSH has a throttling functionality build in to prevent a system from being DDOS&#039;ed by the amount of malicious SSH requests. This throttling can cause the Zabbix server from being denied an SSH connection, of which several failures fire this trigger. This hypothesis can be proven with a `journalctl -u ssh | grep &#039;MaxStartupsThrottling&#039;` (you probably want to select a relevant time period with `--since &amp;quot;2 hours ago&amp;quot;` or something similar to prevent having to process a month of logging). You can then compare the throttling start and end times with the timestamps of the item data itself. The resolution for the issue is to add our custom ssh configuration [https://chat.empiresmod.com/era/pl/oxiu4ark4t8e5paueftr981iyo Custom SSH Configuration].&lt;br /&gt;
* No backup for 3 days: Are S3 backup is very slow. Not much to prove as an underlying issue here. What needs to be done is check that the backup process is ongoing. The Zabbix latest data can be checked to verify that backups are running by checking that that days backups were done for the smaller buckets. The devteam email can be checked for if the backup process could not start on day due to it already running (it takes 24+ hours, and an attempt to start it is done each day by cron).&lt;br /&gt;
* git.* HTTPS is down: On Sunday, Git gets automaticly updated, but this incurs some downtime. This is usually short enough to not be reported to Mattermost as per our settings, but sometimes it&#039;s longer. If the service does not stay down, for more then 20 minutes, the issue can be just resolved.&lt;br /&gt;
&lt;br /&gt;
==== Resolve incident + cleanup ====&lt;br /&gt;
When you&#039;ve executed and verified the resolution in the previous steps we can proceed resolving the issue in our Mattermost integration. Resolving an incident can be done by doing the following:&lt;br /&gt;
# Verify that the trigger is no longer firing. An incident will be immediatly re-opened if the trigger is still firing, and the incident cannot be considered resolved if the trigger is still firing. If the trigger is still firing but you&#039;re sure that you&#039;ve resolved the problem, you might need to force the item the trigger depends on to update. This can be done by finding the item in the host&#039;s configuration on Zabbix and selecting &#039;Execute Now&#039;, after a short period this should force Zabbix to re-execute the item. You can check the timestamps in the latest data of an item to check if it was updated.&lt;br /&gt;
# Type the magic string &#039;I agree that this has been fully resolved&#039; in the thread. During the next iteration of the Zabbix-Mattermost integration the incident will be closed.&lt;br /&gt;
&lt;br /&gt;
Unfortunatly, some problems cause multiple critical and non-critical triggers to fire. This means we have to check Zabbix and Mattermost for other fired triggers and ongoing incidents. The goal is to identify critical and non-critical incidents that were caused by the incident/underlying issue you just resolved.&lt;br /&gt;
# First, these incidents need to be acknowledged on Zabbix, and in the acknowledgement message you mention the incident/problem that caused this.&lt;br /&gt;
# Next, check the incident tracked by the integration on Mattermost using the `?ongoing` command. Resolve incidents that were (re-)opened by this incident by executing the following steps. If the first two fail (problem still persists, trigger is still firing), the incident needs to considered it&#039;s own issue and the relevant process needs to be followed (critical or non-critical depending on criticality).&lt;br /&gt;
## Ensuring the mentioned problem is no longer observable&lt;br /&gt;
## The trigger has resolved (You might need to force an update with `Execute Now`).&lt;br /&gt;
## Posting a link to the main incident you resolved with the comment that the underlying problem was resolved in that thread.&lt;br /&gt;
## Closing the incident with the magic string `I agree that this has been fully resolved`.&lt;br /&gt;
&lt;br /&gt;
When you are done, there should be no more critical triggers firing in Zabbix or open in the Zabbix-Mattermost intergration, for which no-one has taken responsibility or you have taken responsibility for and are not actively handling.&lt;br /&gt;
&lt;br /&gt;
===Additional context===&lt;br /&gt;
* Critical incidents are posted in &#039;&#039;&#039;Infrastructure&#039;&#039;&#039;.&lt;br /&gt;
* When it is being tracked on GitLab a heavy check mark is added to the message.&lt;br /&gt;
* Responses on the thread and on GitLab are automatically synced (to some extend)&lt;br /&gt;
* When you reply with &#039;&#039;&#039;I agree that this has been fully resolved&#039;&#039;&#039; eventually our Zabbix-Mattermost integration will pick this up and a green check mark is added to the message.&lt;br /&gt;
&lt;br /&gt;
== Non-Critical incidents ==&lt;br /&gt;
* Non-critical incidents are acknowledged within 9 hours and resolved within one week.&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix and state who is responsible for resolving this in the description&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# If there is no resolution to the incident, evaluate if the trigger needs updating/disabling&lt;br /&gt;
# Resolve incident&lt;br /&gt;
&lt;br /&gt;
== Informational incidents ==&lt;br /&gt;
* Informational incidents are acknowledged within 72 hours&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix&lt;br /&gt;
# Sanity check the event, post result in thread&lt;br /&gt;
# If action needed, perform action&lt;br /&gt;
&lt;br /&gt;
== If an incident is reported in the SRE channel by other means than the Zabbix-Mattermost intergration ==&lt;br /&gt;
# Acknowledge receipt.&lt;br /&gt;
# Classify the incident as critical, non-critical, or informational.&lt;br /&gt;
# Create an issue using the `[https://chat.empiresmod.com/era/pl/xt669m4fcprfbciwee9iiq5xte ?track]` command and state that you&#039;ve done so.&lt;br /&gt;
# Proceed to treat the incident according to the criticality you just classified it as. (So for a critical incident, it means you now start the critical incident handling process)&lt;br /&gt;
&lt;br /&gt;
== Handover ==&lt;br /&gt;
When handing over the responsibility of first responder (FR), the following needs to happen:&lt;br /&gt;
* Acting FR adds the upcoming FR the the IPA sla-first-responder user group (Optional: and enables Zabbix calling for that person if they have that set by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; Trigger actions)&lt;br /&gt;
* The upcoming FR makes sure they are aware of the state of the SLA and knows what questions they wants to ask the acting FR.&lt;br /&gt;
The following steps can be done async or in person:&lt;br /&gt;
* The acting FR announces/informs the upcoming FR has been added to the sla-first-responder group (In Mattermost&#039;s organisational channel if asynq).&lt;br /&gt;
* If the acting FR wants to hand over responsibility for any ongoing incident they also state which incidents they want the upcoming FR to take over.&lt;br /&gt;
* If there are any particularities the upcoming FR needs to be aware of, those are shared.&lt;br /&gt;
* The upcoming FR asks their questions until they are satisfied and able to take over the FR&lt;br /&gt;
* The upcoming FR announces/informs that they are now the acting FR over Mattermost&#039;s organisational channel&lt;br /&gt;
* The now acting FR removes the previous FR from IPA the sla-first-responder user group (Optional: and disables Zabbix calling for that person if they had that enabled by going to Zabbix &amp;gt; Configuration &amp;gt; Actions &amp;gt; Trigger actions)&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=293</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=293"/>
		<updated>2024-05-20T14:54:33Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Revert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
  border-radius: 0 0 0 14px;&lt;br /&gt;
  box-shadow: var(--shadow-elevation-low);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 1px;&lt;br /&gt;
	&lt;br /&gt;
	border-radius: 14px 0 0 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo a {&lt;br /&gt;
	background-size: contain;&lt;br /&gt;
    width: 8em;&lt;br /&gt;
    margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 999px) {&lt;br /&gt;
	#p-personal,&lt;br /&gt;
	.vector-user-menu-legacy {&lt;br /&gt;
 		position: absolute;&lt;br /&gt;
    	top: 0;&lt;br /&gt;
    	left: 0;&lt;br /&gt;
    	right: 0;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content {&lt;br /&gt;
  		display: block;&lt;br /&gt;
		width: 100%;&lt;br /&gt;
    	padding: 8px 12px;&lt;br /&gt;
    	overflow: auto;&lt;br /&gt;
	    box-sizing: border-box;&lt;br /&gt;
	}&lt;br /&gt;
   &lt;br /&gt;
    #p-personal ul,&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content-list {&lt;br /&gt;
  		white-space: nowrap;&lt;br /&gt;
  		display: block;&lt;br /&gt;
  		padding-left: 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	.vector-user-menu-legacy .mw-list-item {&lt;br /&gt;
		float: none;    	&lt;br /&gt;
		display: inline-block;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=292</id>
		<title>MediaWiki:Mobile.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Mobile.css&amp;diff=292"/>
		<updated>2024-05-20T14:54:14Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;/* All CSS here will be loaded for users of the mobile site */  #mw-head, #mw-panel { 	display: none; }  #footer, #content { 	margin-left: 0; }&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* All CSS here will be loaded for users of the mobile site */&lt;br /&gt;
&lt;br /&gt;
#mw-head, #mw-panel {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer, #content {&lt;br /&gt;
	margin-left: 0;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=291</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=291"/>
		<updated>2024-05-20T14:52:46Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Maybe responsive?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
  border-radius: 0 0 0 14px;&lt;br /&gt;
  box-shadow: var(--shadow-elevation-low);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 1px;&lt;br /&gt;
	&lt;br /&gt;
	border-radius: 14px 0 0 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo a {&lt;br /&gt;
	background-size: contain;&lt;br /&gt;
    width: 8em;&lt;br /&gt;
    margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 999px) {&lt;br /&gt;
	&lt;br /&gt;
	body.skin--responsive {&lt;br /&gt;
		#mw-head, #mw-panel {&lt;br /&gt;
			display: none;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		#footer, #content {&lt;br /&gt;
			margin-left: 0;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	#p-personal,&lt;br /&gt;
	.vector-user-menu-legacy {&lt;br /&gt;
 		position: absolute;&lt;br /&gt;
    	top: 0;&lt;br /&gt;
    	left: 0;&lt;br /&gt;
    	right: 0;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content {&lt;br /&gt;
  		display: block;&lt;br /&gt;
		width: 100%;&lt;br /&gt;
    	padding: 8px 12px;&lt;br /&gt;
    	overflow: auto;&lt;br /&gt;
	    box-sizing: border-box;&lt;br /&gt;
	}&lt;br /&gt;
   &lt;br /&gt;
    #p-personal ul,&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content-list {&lt;br /&gt;
  		white-space: nowrap;&lt;br /&gt;
  		display: block;&lt;br /&gt;
  		padding-left: 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	.vector-user-menu-legacy .mw-list-item {&lt;br /&gt;
		float: none;    	&lt;br /&gt;
		display: inline-block;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=290</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=290"/>
		<updated>2024-05-18T15:52:22Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
  border-radius: 0 0 0 14px;&lt;br /&gt;
  box-shadow: var(--shadow-elevation-low);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 1px;&lt;br /&gt;
	&lt;br /&gt;
	border-radius: 14px 0 0 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo a {&lt;br /&gt;
	background-size: contain;&lt;br /&gt;
    width: 8em;&lt;br /&gt;
    margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 999px) {&lt;br /&gt;
	#p-personal,&lt;br /&gt;
	.vector-user-menu-legacy {&lt;br /&gt;
 		position: absolute;&lt;br /&gt;
    	top: 0;&lt;br /&gt;
    	left: 0;&lt;br /&gt;
    	right: 0;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content {&lt;br /&gt;
  		display: block;&lt;br /&gt;
		width: 100%;&lt;br /&gt;
    	padding: 8px 12px;&lt;br /&gt;
    	overflow: auto;&lt;br /&gt;
	    box-sizing: border-box;&lt;br /&gt;
	}&lt;br /&gt;
   &lt;br /&gt;
    #p-personal ul,&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content-list {&lt;br /&gt;
  		white-space: nowrap;&lt;br /&gt;
  		display: block;&lt;br /&gt;
  		padding-left: 0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	.vector-user-menu-legacy .mw-list-item {&lt;br /&gt;
		float: none;    	&lt;br /&gt;
		display: inline-block;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=289</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=289"/>
		<updated>2024-05-18T15:50:56Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
  border-radius: 0 0 0 14px;&lt;br /&gt;
  box-shadow: var(--shadow-elevation-low);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 1px;&lt;br /&gt;
	&lt;br /&gt;
	border-radius: 14px 0 0 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo a {&lt;br /&gt;
	background-size: contain;&lt;br /&gt;
    width: 8em;&lt;br /&gt;
    margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 999px) {&lt;br /&gt;
	.vector-user-menu-legacy {&lt;br /&gt;
 		position: absolute;&lt;br /&gt;
    	top: 0;&lt;br /&gt;
    	left: 0;&lt;br /&gt;
    	right: 0;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content {&lt;br /&gt;
  		display: block;&lt;br /&gt;
		width: 100%;&lt;br /&gt;
    	padding: 8px 12px;&lt;br /&gt;
    	overflow: auto;&lt;br /&gt;
	    box-sizing: border-box;&lt;br /&gt;
	}&lt;br /&gt;
  &lt;br /&gt;
	.vector-user-menu-legacy .vector-menu-content-list {&lt;br /&gt;
  		whitespace: nowrap;&lt;br /&gt;
  		display: block;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	.vector-user-menu-legacy .mw-list-item {&lt;br /&gt;
		float: none;    	&lt;br /&gt;
		display: inline-block;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=288</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=288"/>
		<updated>2024-05-18T15:44:52Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Better responsive top-menu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
  border-radius: 0 0 0 14px;&lt;br /&gt;
  box-shadow: var(--shadow-elevation-low);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 1px;&lt;br /&gt;
	&lt;br /&gt;
	border-radius: 14px 0 0 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo a {&lt;br /&gt;
	background-size: contain;&lt;br /&gt;
    width: 8em;&lt;br /&gt;
    margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media screen and (max-width: 999px) {&lt;br /&gt;
  .vector-user-menu-legacy .vector-menu-content {&lt;br /&gt;
  	display: block;&lt;br /&gt;
	width: 100vw;&lt;br /&gt;
    padding: 0 8px 12px;&lt;br /&gt;
    overflow: auto;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  .vector-user-menu-legacy .vector-menu-content .mw-list-item {&lt;br /&gt;
	float: none;    	&lt;br /&gt;
  }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Training_and_self-study&amp;diff=287</id>
		<title>Training and self-study</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Training_and_self-study&amp;diff=287"/>
		<updated>2024-05-18T15:28:58Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;At Delft Solutions we welcome training and self-study, if you think it will benefit you in your role or the company as a whole.   It is often possible to:  * attend conferences related to your work * purchase books (physical and epubs) * follow courses  There is no strict yearly budget, but please ask management. If a case can be made that it&amp;#039;s helpful, it is generally approved.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions we welcome training and self-study, if you think it will benefit you in your role or the company as a whole. &lt;br /&gt;
&lt;br /&gt;
It is often possible to:&lt;br /&gt;
&lt;br /&gt;
* attend conferences related to your work&lt;br /&gt;
* purchase books (physical and epubs)&lt;br /&gt;
* follow courses&lt;br /&gt;
&lt;br /&gt;
There is no strict yearly budget, but please ask management. If a case can be made that it&#039;s helpful, it is generally approved.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Sick_leave&amp;diff=286</id>
		<title>Sick leave</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Sick_leave&amp;diff=286"/>
		<updated>2024-05-18T15:26:46Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;Delft Solutions follows [https://business.gov.nl/running-your-business/staff/terms-of-employment/sick-leave-your-employee-calls-in-sick/ the Dutch law regarding sick leave].   == Process ==  * If you get ill, you must report this as soon as possible, at least before the start of the working day, or as it happens during the day. * If you get ill, and you scheduled your week beforehand, you can log those hours as sick leave. * If you get ill, and you work adhoc / have not...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Delft Solutions follows [https://business.gov.nl/running-your-business/staff/terms-of-employment/sick-leave-your-employee-calls-in-sick/ the Dutch law regarding sick leave]. &lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* If you get ill, you must report this as soon as possible, at least before the start of the working day, or as it happens during the day.&lt;br /&gt;
* If you get ill, and you scheduled your week beforehand, you can log those hours as sick leave.&lt;br /&gt;
* If you get ill, and you work adhoc / have not scheduled your week beforehand, the first day is ignored. This is the default for those who choose to work irregularly.&lt;br /&gt;
* If you get ill during paid holiday leave, please report this so your holidays can be reimbursed.&lt;br /&gt;
* You are free to share your reason for illness, but you do not need to. You will never be asked by management.&lt;br /&gt;
* Instead, after a period of time, a company doctor will make an inquiry and advice both you and management what the next steps are.&lt;br /&gt;
* If possible, hand-over any work both when falling ill and when returning to work. However, if circumstances make this hard or impossible, do not strain yourself further trying to hand-over work.&lt;br /&gt;
&lt;br /&gt;
At Delft Solutions various people are in regular contact with immunocompromised people.  For this reason, and in order to prevent spreading illness, you will work from home if you feel or expect to be or become symptomatic of any illness, unless you are certain it cannot be spread (like hay fever). Please talk to management to ensure you have a workable environment at home, as they can help you (including financially) to set this up if it&#039;s lacking.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Bonus_allocation&amp;diff=285</id>
		<title>Bonus allocation</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Bonus_allocation&amp;diff=285"/>
		<updated>2024-05-18T15:15:52Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;After each quarter has ended there is a company wide Quarterly update meeting in which we talk about the past and upcoming quarter. This is generally scheduled 1 to 2 weeks after the quarter&amp;#039;s end. Divergence from the bonus calculation is shared during this meeting.  == Process ==  * Under regular circumstances in order to calculate the bonus we take the quarterly throughput and deduct the bonus threshold.  * The remainder is capped at the maximum bonus throughput and mu...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;After each quarter has ended there is a company wide Quarterly update meeting in which we talk about the past and upcoming quarter. This is generally scheduled 1 to 2 weeks after the quarter&#039;s end. Divergence from the bonus calculation is shared during this meeting.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* Under regular circumstances in order to calculate the bonus we take the quarterly throughput and deduct the bonus threshold. &lt;br /&gt;
* The remainder is capped at the maximum bonus throughput and multiplied against the bonus amount. &lt;br /&gt;
* If this yields a nonzero amount, the bonus is awarded to each team member that has logged at least one working hour, prorated to the average number of hours a week worked (which should be 32 by default for everyone).&lt;br /&gt;
* The bonus amount is communicated to the accountants and appears on the next wage slip.&lt;br /&gt;
* After the bonus is calculated, the amount in liquid funds is taken and checked against the desired working capital.&lt;br /&gt;
* Any funds after deducting the desired working capital and quarterly bonus costs is the quarterly dividend to be shared amongst the shareholders.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=284</id>
		<title>Internal</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=284"/>
		<updated>2024-05-16T13:09:31Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Finance ==&lt;br /&gt;
&lt;br /&gt;
=== Exact ===&lt;br /&gt;
&lt;br /&gt;
* [[booking bonus|Booking bonus]]&lt;br /&gt;
* [[booking wages|Booking wages]]&lt;br /&gt;
* [[new receipt|Enter a new receipt]]&lt;br /&gt;
* [[reconciliation|Reconciliation of transaction]]&lt;br /&gt;
* [[invoicing|Send an invoice]]&lt;br /&gt;
* [[payment reminders|Send payment reminder]]&lt;br /&gt;
* [[invoice approval|Process for approving invoices (/filed receipts)]]&lt;br /&gt;
&lt;br /&gt;
=== Bunq ===&lt;br /&gt;
&lt;br /&gt;
* [[top up account|Top up expense account]]&lt;br /&gt;
&lt;br /&gt;
== Work Process ==&lt;br /&gt;
&lt;br /&gt;
* [[Definition of done|Definition of Done]]&lt;br /&gt;
* [[Incident Handling|Incident Handling]]&lt;br /&gt;
&lt;br /&gt;
== Internal Process ==&lt;br /&gt;
&lt;br /&gt;
* [[12 percent|12% time]]&lt;br /&gt;
* [[Annual leave|Annual leave]]&lt;br /&gt;
* [[Bonus allocation|Bonus allocation]]&lt;br /&gt;
* [[Calamity leave|Calamity leave]]&lt;br /&gt;
* [[Overtime|Overtime]]&lt;br /&gt;
* [[Retrospectives|Retrospectives]]&lt;br /&gt;
* [[Sick leave|Sick leave]]&lt;br /&gt;
* [[Training and self-study|Training and Self-Study]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
* Era Inventory [[project_era_inventory_api|API Description]]&lt;br /&gt;
&lt;br /&gt;
== SRE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To be further populated with guide from drive&#039;&#039;&lt;br /&gt;
* [[create gitlab runner host|Create a GitLab runner host]]&lt;br /&gt;
* [[vm setup|Create a (Debian) VM]]&lt;br /&gt;
* [[border reboot|Reboot border without downtime]]&lt;br /&gt;
* [[WS Proxmox node reboot|Reboot WS Proxmox node without downtime]]&lt;br /&gt;
* [[Resize VM Disk]]&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
* [[standard tools|Standard Tools]]&lt;br /&gt;
* [[list of unfurl debuggers|List of unfurl debuggers]]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Retrospectives&amp;diff=283</id>
		<title>Retrospectives</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Retrospectives&amp;diff=283"/>
		<updated>2024-05-16T13:09:21Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;At Delft Solutions most teams will hold a retrospective each week to see where process can be improved.  == Process ==  During the week, issues with the current process (for example a process not being followed by someone, or a process not taking care of a specific incident) will be listed in the [https://chat.empiresmod.com/era/channels/retro ~Retro channel]. Once a week, generally on Friday, these points are discussed in a timeboxed meeting. There is &amp;#039;&amp;#039;always&amp;#039;&amp;#039; an outc...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions most teams will hold a retrospective each week to see where process can be improved.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
During the week, issues with the current process (for example a process not being followed by someone, or a process not taking care of a specific incident) will be listed in the [https://chat.empiresmod.com/era/channels/retro ~Retro channel]. Once a week, generally on Friday, these points are discussed in a timeboxed meeting. There is &#039;&#039;always&#039;&#039; an outcome to each item, where everyone in the team agrees that is how we wil move forward. That means that we cannot just do nothing, but we can &#039;&#039;decide&#039;&#039; to not change anything (and have it happen again next time). In most cases the resolution will be to amend the process at hand.&lt;br /&gt;
&lt;br /&gt;
This also means that you cannot diverge from a current process &#039;&#039;during&#039;&#039; the week, but only after discussing it at the Retrospective.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Overtime&amp;diff=282</id>
		<title>Overtime</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Overtime&amp;diff=282"/>
		<updated>2024-05-16T13:06:19Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions we don&#039;t like overtime because everyone is entitled to off-time such as evenings or weekends. Structural / recurring overtime is not allowed without a written request and approval and will only be granted under specific circumstances.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* If you accidentally work longer than expected (say an hour), you can self-manage it the next week by working an hour shorter. Hours registered going over your weekly amount (of 32 hours), will automatically be added to your available holiday/vacation hours.&lt;br /&gt;
* If you intend to work a significant amount of time on top of your regular hours, for example because you want to meet a deadline, you must request this by informing management. Under normal circumstances requests like these will not be granted. Instead, management will often help you communicate to clients that delays are to be expected, or find a way to make the deadline without overtime. In the case the overtime is granted, because of the above, your hours are reimbursed at a 1:1 rate automatically.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Overtime&amp;diff=281</id>
		<title>Overtime</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Overtime&amp;diff=281"/>
		<updated>2024-05-16T13:05:02Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;At Delft Solutions we don&amp;#039;t like overtime because everyone is entitled to off-time such as evenings or weekends. Structural / recurring overtime is not allowed without a written request and approval and will only be granted under specific circumstances.  == Process ==  * If you accidentally work longer than expected (say an hour), you can self-manage it the next week by working an hour shorter. Hours registered going over your weekly amount (of 32 hours), will automatica...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions we don&#039;t like overtime because everyone is entitled to off-time such as evenings or weekends. Structural / recurring overtime is not allowed without a written request and approval and will only be granted under specific circumstances.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* If you accidentally work longer than expected (say an hour), you can self-manage it the next week by working an hour shorter. Hours registered going over your weekly amount (of 32 hours), will automatically be added to your available holiday/vacation hours.&lt;br /&gt;
* If you intend to work a significant amount of time on top of your regular hours, for example because you want to meet a deadline, you must request this by informing management. Under normal circumstances requests like these will not be granted. Instead, management will often help you communicate to clients that delays are to be expected, or find a way to make the deadline without overtime.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Calamity_leave&amp;diff=280</id>
		<title>Calamity leave</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Calamity_leave&amp;diff=280"/>
		<updated>2024-05-16T13:01:05Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;We followed the official rules and guidance by the Dutch government regarding short-term and long-term care leave.   &amp;#039;&amp;#039;&amp;#039;Short-term care leave is always granted.&amp;#039;&amp;#039;&amp;#039;  == Resources ==   * [https://business.gov.nl/regulation/leave-schemes/ business.gov.nl] * [https://www.rijksoverheid.nl/onderwerpen/zorgverlof/vraag-en-antwoord/duur-zorgverlof rijksoverheid.nl (Dutch)]&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;We followed the official rules and guidance by the Dutch government regarding short-term and long-term care leave. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Short-term care leave is always granted.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Resources == &lt;br /&gt;
&lt;br /&gt;
* [https://business.gov.nl/regulation/leave-schemes/ business.gov.nl]&lt;br /&gt;
* [https://www.rijksoverheid.nl/onderwerpen/zorgverlof/vraag-en-antwoord/duur-zorgverlof rijksoverheid.nl (Dutch)]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Annual_leave&amp;diff=279</id>
		<title>Annual leave</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Annual_leave&amp;diff=279"/>
		<updated>2024-05-16T12:57:36Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;Everyone is entitled to annual leave and Delft Solutions encourages everyone to take their vacation days.  == Process ==  In general everything will be approved, as long as we can ensure SLOs. Please request your annual leave via the [https://chat.empiresmod.com/era/channels/company ~Organisational channel]. In case of a conflict meeting the SLOs, if no one is willing to give up the overlap, the first one who made the request following this process will be able to take t...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Everyone is entitled to annual leave and Delft Solutions encourages everyone to take their vacation days.&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
In general everything will be approved, as long as we can ensure SLOs. Please request your annual leave via the [https://chat.empiresmod.com/era/channels/company ~Organisational channel]. In case of a conflict meeting the SLOs, if no one is willing to give up the overlap, the first one who made the request following this process will be able to take their annual leave that moment.&lt;br /&gt;
&lt;br /&gt;
* When your annual leave is coming up, please ensure a handover of all outstanding tasks. &lt;br /&gt;
* When someone is on annual leave, please ensure you try everything else before contacting them. This time is supposed to be sacred. If we treat it as such for everyone, we also know that getting a call during annual leave can be considered a last effort.&lt;br /&gt;
* When you are on annual leave and you get a call, &#039;&#039;&#039;you are entitled to ignore it&#039;&#039;&#039;, and emergency work done during annual leave is reimbursed as holiday not taken.&lt;br /&gt;
* When you are on annual leave and you fall ill, please communicate this to management so we can reimburse the sick days. &lt;br /&gt;
&lt;br /&gt;
== Management ==&lt;br /&gt;
&lt;br /&gt;
Max and Derk-Jan will not be taken leave at the same time.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=12_percent&amp;diff=278</id>
		<title>12 percent</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=12_percent&amp;diff=278"/>
		<updated>2024-05-16T12:52:11Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions 12% of your paid working hours can be spend on anything you like, preferably useful to either your role or the company. This can include learning more, or developing software tools for in house use, or writing blog posts for the company website.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;It&#039;s &amp;quot;something you think is useful, but doesn&#039;t go on the backlog&amp;quot;.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you feel like it, during [[Retrospectives|the retrospective]] you can demo what you&#039;ve been working on.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=12_percent&amp;diff=277</id>
		<title>12 percent</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=12_percent&amp;diff=277"/>
		<updated>2024-05-16T12:51:49Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;At Delft Solutions 12% of your paid working hours can be spend on anything you like, preferably useful to either your role or the company. This can include learning more, or developing software tools for in house use, or writing blog posts for the company website.  &amp;#039;&amp;#039;It&amp;#039;s &amp;quot;something you think is useful, but doesn&amp;#039;t go on the backlog&amp;quot;.&amp;#039;&amp;#039;  If you feel like it, during Retrospectives you can demo what you&amp;#039;ve been working on.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;At Delft Solutions 12% of your paid working hours can be spend on anything you like, preferably useful to either your role or the company. This can include learning more, or developing software tools for in house use, or writing blog posts for the company website.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;It&#039;s &amp;quot;something you think is useful, but doesn&#039;t go on the backlog&amp;quot;.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If you feel like it, during [[the retrospective|Retrospectives]] you can demo what you&#039;ve been working on.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=276</id>
		<title>Internal</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=276"/>
		<updated>2024-05-16T12:38:41Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Finance ==&lt;br /&gt;
&lt;br /&gt;
=== Exact ===&lt;br /&gt;
&lt;br /&gt;
* [[booking bonus|Booking bonus]]&lt;br /&gt;
* [[booking wages|Booking wages]]&lt;br /&gt;
* [[new receipt|Enter a new receipt]]&lt;br /&gt;
* [[reconciliation|Reconciliation of transaction]]&lt;br /&gt;
* [[invoicing|Send an invoice]]&lt;br /&gt;
* [[payment reminders|Send payment reminder]]&lt;br /&gt;
* [[invoice approval|Process for approving invoices (/filed receipts)]]&lt;br /&gt;
&lt;br /&gt;
=== Bunq ===&lt;br /&gt;
&lt;br /&gt;
* [[top up account|Top up expense account]]&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* [[definition of done|Definition of Done]]&lt;br /&gt;
* [[Incident Handling|Incident Handling]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
* Era Inventory [[project_era_inventory_api|API Description]]&lt;br /&gt;
&lt;br /&gt;
== SRE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To be further populated with guide from drive&#039;&#039;&lt;br /&gt;
* [[create gitlab runner host|Create a GitLab runner host]]&lt;br /&gt;
* [[vm setup|Create a (Debian) VM]]&lt;br /&gt;
* [[border reboot|Reboot border without downtime]]&lt;br /&gt;
* [[WS Proxmox node reboot|Reboot WS Proxmox node without downtime]]&lt;br /&gt;
* [[Resize VM Disk]]&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
* [[standard tools|Standard Tools]]&lt;br /&gt;
* [[list of unfurl debuggers|List of unfurl debuggers]]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=257</id>
		<title>Incident Handling</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Incident_Handling&amp;diff=257"/>
		<updated>2024-05-07T15:17:49Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Visual status changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Critical incidents ==&lt;br /&gt;
* Critical incidents are resolved within 16 hours.&lt;br /&gt;
&lt;br /&gt;
===Checklist===&lt;br /&gt;
# Acknowledge on Zabbix and state who is responsible for resolving this in the description&lt;br /&gt;
# Determine affected clients&lt;br /&gt;
# Communicate to affected clients that the issue is being investigated&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# Resolve incident&lt;br /&gt;
&lt;br /&gt;
===Additional context===&lt;br /&gt;
* Critical incidents are posted in &#039;&#039;&#039;Infrastructure&#039;&#039;&#039;.&lt;br /&gt;
* When it is being tracked on GitLab a heavy check mark is added to the message.&lt;br /&gt;
* Responses on the thread and on GitLab are automatically synced (to some extend)&lt;br /&gt;
* When you reply with &#039;&#039;&#039;I agree that this has been fully resolved&#039;&#039;&#039; eventually Zabbix will pick this up and a green check mark is added to the message.&lt;br /&gt;
&lt;br /&gt;
== Non-Critical incidents ==&lt;br /&gt;
* Non-critical incidents are acknowledged within 9 hours and resolved within one week.&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix and state who is responsible for resolving this in the description&lt;br /&gt;
# Communicate plan/next steps (even if that is gathering information)&lt;br /&gt;
# Communicate findings/results of executed plan, go back to previous step if not resolved&lt;br /&gt;
# If there is no resolution to the incident, evaluate if the trigger needs updating/disabling&lt;br /&gt;
# Resolve incident&lt;br /&gt;
&lt;br /&gt;
== Informational incidents ==&lt;br /&gt;
* Informational incidents are acknowledged within 72 hours&lt;br /&gt;
&lt;br /&gt;
Checklist&lt;br /&gt;
# Acknowledge on Zabbix&lt;br /&gt;
# Sanity check the event, post result in thread&lt;br /&gt;
# If action needed, perform action&lt;br /&gt;
&lt;br /&gt;
== If an incident is reported in the SRE channel by a human ==&lt;br /&gt;
* Acknowledge receipt.&lt;br /&gt;
* Classify the incident as critical, non-critical, or informational.&lt;br /&gt;
* Create an issue and state that you&#039;ve done so.&lt;br /&gt;
&lt;br /&gt;
== Handover ==&lt;br /&gt;
When handing over the responsibility of first responder (FR), the following needs to happen:&lt;br /&gt;
* Acting FR adds the upcoming FR the the IPA sla-first-responder user group, and enables Zabbix calling for that person&lt;br /&gt;
* The upcoming FR makes sure he is aware of the state of the SLA and knows what questions he wants to ask the acting FR&lt;br /&gt;
The following steps can be done async or in person:&lt;br /&gt;
* The acting FR announces/informs the upcoming FR has been added to the sla-first-responder group (In Mattermost&#039;s organisational channel if asynq).&lt;br /&gt;
* If the acting FR wants to hand over responsibility for any ongoing incident he also states which incidents he want the upcoming FR to take over.&lt;br /&gt;
* If there are any particularities the upcoming FR needs to be aware of, he shares them then.&lt;br /&gt;
* The upcoming FR asks his questions until he is satisfied and able to take over the FR&lt;br /&gt;
* The upcoming FR announces/informs that he is now the acting FR over Mattermost&#039;s organisational channel&lt;br /&gt;
* The now acting FR removes the previous FR from IPA the sla-first-responder user group, and disables Zabbix calling for that person&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Error/OpusSafety::NotFoundError&amp;diff=244</id>
		<title>Error/OpusSafety::NotFoundError</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Error/OpusSafety::NotFoundError&amp;diff=244"/>
		<updated>2024-03-09T12:25:09Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;You encountered this error on [https://cloud.opus-safety.co.uk/ Opus Safety Cloud].  * If this happened after clicking a link on the Opus Safety Cloud platform, please report it [https://sites.google.com/opus-safety.co.uk/opus-help/home via the support center]. * If this happened after opening a bookmark, or following a link on a different platform or email, please update the bookmark or let the sender know.&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;You encountered this error on [https://cloud.opus-safety.co.uk/ Opus Safety Cloud].&lt;br /&gt;
&lt;br /&gt;
* If this happened after clicking a link on the Opus Safety Cloud platform, please report it [https://sites.google.com/opus-safety.co.uk/opus-help/home via the support center].&lt;br /&gt;
* If this happened after opening a bookmark, or following a link on a different platform or email, please update the bookmark or let the sender know.&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=List_of_unfurl_debuggers&amp;diff=243</id>
		<title>List of unfurl debuggers</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=List_of_unfurl_debuggers&amp;diff=243"/>
		<updated>2024-03-07T20:38:50Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;* Facebook: [https://developers.facebook.com/docs/sharing/webmasters#markup debugger] [https://developers.facebook.com/docs/sharing/webmasters#markup docs] * Slack: [https://api.slack.com/tools/unfurl-debugger debugger] [https://api.slack.com/reference/messaging/link-unfurling docs]&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Facebook: [https://developers.facebook.com/docs/sharing/webmasters#markup debugger] [https://developers.facebook.com/docs/sharing/webmasters#markup docs]&lt;br /&gt;
* Slack: [https://api.slack.com/tools/unfurl-debugger debugger] [https://api.slack.com/reference/messaging/link-unfurling docs]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=242</id>
		<title>Internal</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=242"/>
		<updated>2024-03-07T20:35:03Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Other */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Finance ==&lt;br /&gt;
&lt;br /&gt;
=== Exact ===&lt;br /&gt;
&lt;br /&gt;
* [[booking bonus|Booking bonus]]&lt;br /&gt;
* [[booking wages|Booking wages]]&lt;br /&gt;
* [[new receipt|Enter a new receipt]]&lt;br /&gt;
* [[reconciliation|Reconciliation of transaction]]&lt;br /&gt;
* [[invoicing|Send an invoice]]&lt;br /&gt;
* [[payment reminders|Send payment reminder]]&lt;br /&gt;
&lt;br /&gt;
=== Bunq ===&lt;br /&gt;
&lt;br /&gt;
* [[top up account|Top up expense account]]&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* [[definition of done|Definition of Done]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
* Era Inventory [[project_era_inventory_api|API Description]]&lt;br /&gt;
&lt;br /&gt;
== SRE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To be further populated with guide from drive&#039;&#039;&lt;br /&gt;
* [[create gitlab runner host|Create a GitLab runner host]]&lt;br /&gt;
* [[vm setup|Create a (Debian) VM]]&lt;br /&gt;
* [[border reboot|Reboot border without downtime]]&lt;br /&gt;
* [[WS Proxmox node reboot|Reboot WS Proxmox node without downtime]]&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
* [[standard tools|Standard Tools]]&lt;br /&gt;
* [[list of unfurl debuggers|List of unfurl debuggers]]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Standard_tools&amp;diff=215</id>
		<title>Standard tools</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Standard_tools&amp;diff=215"/>
		<updated>2024-02-16T11:44:58Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;== Images ==  * One-off optimisations of PNG, JPEG via [https://squoosh.app/ squoosh.app] * One-off optimisations of SVG via [https://jakearchibald.github.io/svgomg/ SVGOMG] * Optimise PNGs via [https://packages.debian.org/bookworm/optipng optipng] e.g. &amp;#039;&amp;#039;optipng -o7 -preserve&amp;#039;&amp;#039; * Optimise JPEGs via [https://packages.debian.org/bookworm/jpegoptim jpegoptim] e.g. &amp;#039;&amp;#039;jpegoptim --strip-all -m76&amp;#039;&amp;#039; * Process images via [https://packages.debian.org/bookworm/libvips-dev libvips]...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Images ==&lt;br /&gt;
&lt;br /&gt;
* One-off optimisations of PNG, JPEG via [https://squoosh.app/ squoosh.app]&lt;br /&gt;
* One-off optimisations of SVG via [https://jakearchibald.github.io/svgomg/ SVGOMG]&lt;br /&gt;
* Optimise PNGs via [https://packages.debian.org/bookworm/optipng optipng] e.g. &#039;&#039;optipng -o7 -preserve&#039;&#039;&lt;br /&gt;
* Optimise JPEGs via [https://packages.debian.org/bookworm/jpegoptim jpegoptim] e.g. &#039;&#039;jpegoptim --strip-all -m76&#039;&#039;&lt;br /&gt;
* Process images via [https://packages.debian.org/bookworm/libvips-dev libvips]&lt;br /&gt;
&lt;br /&gt;
== Audio ==&lt;br /&gt;
&lt;br /&gt;
* Processing, encoding, or recoding via [https://packages.debian.org/bookworm/ffmpeg ffmpeg]&lt;br /&gt;
&lt;br /&gt;
== Video ==&lt;br /&gt;
&lt;br /&gt;
* Processing, encoding, or recoding via [https://packages.debian.org/bookworm/ffmpeg ffmpeg]&lt;br /&gt;
&lt;br /&gt;
== Formatting ==&lt;br /&gt;
&lt;br /&gt;
* JavaScript, TypeScript, Markdown, YAML, and CSS can be automatically formatted using [https://prettier.io/ prettier]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=214</id>
		<title>Internal</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Internal&amp;diff=214"/>
		<updated>2024-02-16T11:10:57Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Finance ==&lt;br /&gt;
&lt;br /&gt;
=== Exact ===&lt;br /&gt;
&lt;br /&gt;
* [[booking wages|Booking wages]]&lt;br /&gt;
* [[new receipt|Enter a new receipt]]&lt;br /&gt;
* [[reconciliation|Reconciliation of transaction]]&lt;br /&gt;
* [[invoicing|Send an invoice]]&lt;br /&gt;
* [[payment reminders|Send payment reminder]]&lt;br /&gt;
&lt;br /&gt;
=== Bunq ===&lt;br /&gt;
&lt;br /&gt;
* [[top up account|Top up expense account]]&lt;br /&gt;
&lt;br /&gt;
== Process ==&lt;br /&gt;
&lt;br /&gt;
* [[definition of done|Definition of Done]]&lt;br /&gt;
&lt;br /&gt;
== Projects ==&lt;br /&gt;
&lt;br /&gt;
* Era Inventory [[project_era_inventory_api|API Description]]&lt;br /&gt;
&lt;br /&gt;
== SRE ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;To be further populated with guide from drive&#039;&#039;&lt;br /&gt;
* [[create gitlab runner host|Create a GitLab runner host]]&lt;br /&gt;
* [[vm setup|Create a (Debian) VM]]&lt;br /&gt;
* [[border reboot|Reboot border without downtime]]&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
* [[standard tools|Standard Tools]]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Category:Terminology&amp;diff=201</id>
		<title>Category:Terminology</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Category:Terminology&amp;diff=201"/>
		<updated>2023-07-11T11:33:10Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=200</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=200"/>
		<updated>2023-07-11T11:30:29Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
  border-radius: 0 0 0 14px;&lt;br /&gt;
  box-shadow: var(--shadow-elevation-low);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu-tabs-legacy {&lt;br /&gt;
	padding-left: 0;&lt;br /&gt;
	margin-left: 1px;&lt;br /&gt;
	&lt;br /&gt;
	border-radius: 14px 0 0 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo a {&lt;br /&gt;
	background-size: contain;&lt;br /&gt;
    width: 8em;&lt;br /&gt;
    margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=199</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=199"/>
		<updated>2023-07-11T11:24:00Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
&lt;br /&gt;
:root {&lt;br /&gt;
  --shadow-color: 246deg 73% 41%;&lt;br /&gt;
  --shadow-elevation-low:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    0.4px 0.8px 1px -1.2px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1px 2px 2.5px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
  --shadow-elevation-medium:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    0.8px 1.6px 2px -0.8px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    2.1px 4.1px 5.2px -1.7px hsl(var(--shadow-color) / 0.36),&lt;br /&gt;
    5px 10px 12.6px -2.5px hsl(var(--shadow-color) / 0.36);&lt;br /&gt;
  --shadow-elevation-high:&lt;br /&gt;
    0.3px 0.5px 0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    1.5px 2.9px 3.7px -0.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    2.7px 5.4px 6.8px -0.7px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    4.5px 8.9px 11.2px -1.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    7.1px 14.3px 18px -1.4px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    11.2px 22.3px 28.1px -1.8px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    17px 33.9px 42.7px -2.1px hsl(var(--shadow-color) / 0.34),&lt;br /&gt;
    25px 50px 62.9px -2.5px hsl(var(--shadow-color) / 0.34);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=198</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=198"/>
		<updated>2023-07-11T11:21:35Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:link, .vector-menu.vector-menu-portal a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu.vector-menu-portal a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=197</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=197"/>
		<updated>2023-07-11T11:20:30Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html, body {&lt;br /&gt;
  height: auto;&lt;br /&gt;
  min-height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu a[href]:link, .vector-menu a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-menu a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=196</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=MediaWiki:Common.css&amp;diff=196"/>
		<updated>2023-07-11T11:15:51Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Fix CSS menu, maybe&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* CSS placed here will be applied to all skins */&lt;br /&gt;
body {&lt;br /&gt;
  background-image: linear-gradient(245deg, rgba(89,149,255,1) 0%, rgba(104,88,255,1) 100%);&lt;br /&gt;
  background-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs, #mw-head .vectorMenu h3 {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-page-base {&lt;br /&gt;
  background: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-body, .parsoid-body {&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
.mw-body {&lt;br /&gt;
  border-color: rgb(104,88,255);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs ul li {&lt;br /&gt;
  background: #293590;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs span {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  border-left: none;&lt;br /&gt;
  border-right: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre, .mw-code {&lt;br /&gt;
  background-color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
.vectorTabs li.selected span {&lt;br /&gt;
  border: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.selected {&lt;br /&gt;
  background-image: none;&lt;br /&gt;
  background-color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vectorTabs li.new a, .vectorTabs li.new a:visited {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-logo {&lt;br /&gt;
  padding-top: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#mw-panel .portal .body li a:visited {&lt;br /&gt;
  color: #E0E1E4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.new, #p-personal a.new {&lt;br /&gt;
  color: #F05C6C;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a {&lt;br /&gt;
  color: white;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a:visited {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a.external {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a {&lt;br /&gt;
  color: #5E7EFF;&lt;br /&gt;
  text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a:visited {&lt;br /&gt;
  color: #192369;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#content a.new {&lt;br /&gt;
  color: #D15E54;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#footer ul li,&lt;br /&gt;
#mw-panel .portal h3,&lt;br /&gt;
.vectorMenu h3 span {&lt;br /&gt;
  color: #F0F0F2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-navigation a[href]:link, #p-navigation a[href]:visited {&lt;br /&gt;
	color: white;&lt;br /&gt;
	transition: color 150ms ease, opacity 150ms ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-navigation a[href]:hover {&lt;br /&gt;
	opacity: 0.7;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-navigation a[href]:active {&lt;br /&gt;
	opacity: 0.9;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=User:SleeplessByte&amp;diff=195</id>
		<title>User:SleeplessByte</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=User:SleeplessByte&amp;diff=195"/>
		<updated>2023-07-10T21:48:29Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: Created page with &amp;quot;Derk-Jan Karrenbeld  == External links ==  * [https://derk-jan.com Bits and Pieces (Personal Blog)] * [https://github.com/SleeplessByte SleeplessByte on GitHub] * [https://gitlab.com/SleeplessByte SleeplessByte on GitLab] * [https://twitter.com/SleeplessByte @SleeplessByte on Twitter] * [https://exercism.org/profiles/SleeplessByte SleeplessByte on Exercism] * [https://steamcommunity.com/id/derk-jan/ Looking For Amy on Steam] * [https://www...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Profile-1920.jpg|thumb|Derk-Jan Karrenbeld]]&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
* [https://derk-jan.com Bits and Pieces (Personal Blog)]&lt;br /&gt;
* [https://github.com/SleeplessByte SleeplessByte on GitHub]&lt;br /&gt;
* [https://gitlab.com/SleeplessByte SleeplessByte on GitLab]&lt;br /&gt;
* [https://twitter.com/SleeplessByte @SleeplessByte on Twitter]&lt;br /&gt;
* [https://exercism.org/profiles/SleeplessByte SleeplessByte on Exercism]&lt;br /&gt;
* [https://steamcommunity.com/id/derk-jan/ Looking For Amy on Steam]&lt;br /&gt;
* [https://www.linkedin.com/in/derkjankarrenbeld/ Derk-Jan Karrenbeld on LinkedIn]&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=File:Profile-1920.jpg&amp;diff=194</id>
		<title>File:Profile-1920.jpg</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=File:Profile-1920.jpg&amp;diff=194"/>
		<updated>2023-07-10T21:48:09Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Derk-Jan Karrenbeld&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
	<entry>
		<id>https://docs.delftsolutions.nl/index.php?title=Booking_wages&amp;diff=193</id>
		<title>Booking wages</title>
		<link rel="alternate" type="text/html" href="https://docs.delftsolutions.nl/index.php?title=Booking_wages&amp;diff=193"/>
		<updated>2023-07-10T20:55:06Z</updated>

		<summary type="html">&lt;p&gt;SleeplessByte: /* Reconciliation (after payment) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Wage slips ==&lt;br /&gt;
&lt;br /&gt;
# Exact&lt;br /&gt;
# Financieel &amp;gt; Boekingen en grootboekrekeningen &amp;gt; Boekingen &amp;gt; Aanmaken&lt;br /&gt;
# Inkoop &amp;gt; &#039;&#039;&#039;80 - Salarisstroken&#039;&#039;&#039;&lt;br /&gt;
# Add file (wage slip)&lt;br /&gt;
# Beschijving: Salaris periode {YEAR}-{MONTH}-M / {YEAR}-{MONTH}-M {NAME}, Periode: M&lt;br /&gt;
# Totaalbedrag: &#039;&#039;&#039;Totaal netto&#039;&#039;&#039;&lt;br /&gt;
# Line items:&lt;br /&gt;
## &#039;&#039;&#039;Brutto &amp;gt; Salaris&#039;&#039;&#039; as &#039;&#039;&#039;Loon (4000)&#039;&#039;&#039;, &lt;br /&gt;
## &#039;&#039;&#039;Loonheffing&#039;&#039;&#039; as &#039;&#039;&#039;af te dragen loonheffing (1700)&#039;&#039;&#039;&lt;br /&gt;
## &#039;&#039;&#039;Netto &amp;gt; Onkostenvergoeding&#039;&#039;&#039; as &#039;&#039;&#039;Kosten nettovergoedingen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Wage taxes ==&lt;br /&gt;
# Exact&lt;br /&gt;
# Financieel &amp;gt; Boekingen en grootboekrekeningen &amp;gt; Boekingen &amp;gt; Aanmaken&lt;br /&gt;
# Inkoop &amp;gt; &#039;&#039;&#039;80 - Salarisstroken&#039;&#039;&#039;&lt;br /&gt;
# Add file (LH)&lt;br /&gt;
# Beschrijving: {LHnummer en volgnummer}, Periode: D&lt;br /&gt;
## &#039;&#039;&#039;Loonbelasting / premie volksverzekering&#039;&#039;&#039; as &#039;&#039;&#039;Af te dragen loonheffing (1700)&#039;&#039;&#039;&lt;br /&gt;
## &#039;&#039;&#039;Premies&#039;&#039;&#039; as &#039;&#039;&#039;Kosten sociale premies werkgever (4041)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Pension ==&lt;br /&gt;
&lt;br /&gt;
# Exact&lt;br /&gt;
# Financieel &amp;gt; Boekingen en grootboekrekeningen &amp;gt; Boekingen &amp;gt; Aanmaken&lt;br /&gt;
# Inkoop &amp;gt; &#039;&#039;&#039;80 - Salarisstroken&#039;&#039;&#039;&lt;br /&gt;
# Add file (JP)&lt;br /&gt;
# Beschrijving: Pensioen {YEAR}-{MONTH}-M, Periode: IN&lt;br /&gt;
# Totaalbedrag: &#039;&#039;&#039;Amount under pensions on JP&#039;&#039;&#039;&lt;br /&gt;
# Line items:&lt;br /&gt;
## For each person who received pension payment: &#039;&#039;&#039;Pensioenen (4011)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Reconciliation (after payment) ==&lt;br /&gt;
# Financieel &amp;gt; Boekingen en grootboekrekeningen &amp;gt; Overzichten &amp;gt; Kaarten&lt;br /&gt;
# Search for &#039;&#039;&#039;Af te dragen loonheffing (1700)&#039;&#039;&#039;&lt;br /&gt;
# Mark the wage slips together with the IRS slip for wage taxes. The difference at the bottom (e.g. 0.16 EUR) needs to be added to the wage tax document.&lt;br /&gt;
## &#039;&#039;&#039;Af te dragen loonheffing (1700)&#039;&#039;&#039; 0.16 EUR&lt;br /&gt;
## &#039;&#039;&#039;Rekenverschillen (9200)&#039;&#039;&#039; -0.16 EUR&lt;br /&gt;
## Repeat process; difference should now be 0&lt;br /&gt;
# Afletteren; difference should be 0&lt;/div&gt;</summary>
		<author><name>SleeplessByte</name></author>
	</entry>
</feed>