Merge pull request 'feature/init' (#1) from feature/init into master
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
fredagsbar_output/*
|
||||||
0
fredagsbar_output/__init__.py
Normal file
0
fredagsbar_output/__init__.py
Normal file
182
generator.py
Normal file
182
generator.py
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
fredagsbar_ics_generator_v3.py
|
||||||
|
|
||||||
|
Genererer .ics invitationer baseret på JSON stories.
|
||||||
|
Understøtter nu 'hints' i filnavne og headers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
from ics import Calendar, Event
|
||||||
|
from datetime import datetime, date, time, timedelta
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
import uuid
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
# ====== STANDARD INDSTILLINGER ======
|
||||||
|
START_DATE = date(2026, 1, 29)
|
||||||
|
START_TIME = time(15, 00)
|
||||||
|
DURATION_MINUTES = 60
|
||||||
|
TIMEZONE = ZoneInfo("Europe/Copenhagen")
|
||||||
|
OUTPUT_BASE_DIR = "fredagsbar_output"
|
||||||
|
# ====================================
|
||||||
|
|
||||||
|
def load_story(filepath):
|
||||||
|
"""Indlæser JSON fil og validerer strukturen."""
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fejl ved indlæsning af {filepath}: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def next_or_same_friday(d: date) -> date:
|
||||||
|
return d + timedelta(days=(4 - d.weekday()) % 7)
|
||||||
|
|
||||||
|
def sanitize_filename(s: str) -> str:
|
||||||
|
s = re.sub(r"[^\w\s-]", "", s, flags=re.UNICODE)
|
||||||
|
s = re.sub(r"\s+", "_", s.strip())
|
||||||
|
return s[:120]
|
||||||
|
|
||||||
|
def strip_html_tags(text: str) -> str:
|
||||||
|
clean = re.compile('<.*?>')
|
||||||
|
return re.sub(clean, '', text)
|
||||||
|
|
||||||
|
def inject_outlook_lines(ical_text: str, html_description: str) -> str:
|
||||||
|
"""Indsætter Outlook-specifikke linjer og HTML beskrivelse."""
|
||||||
|
injection_status = "TRANSP:OPAQUE\r\nX-MICROSOFT-CDO-BUSYSTATUS:BUSY\r\n"
|
||||||
|
# Outlook kræver often at HTML er på én linje eller foldet korrekt
|
||||||
|
html_oneline = html_description.replace("\n", "")
|
||||||
|
injection_html = f"X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE html><html><body>{html_oneline}</body></html>\r\n"
|
||||||
|
|
||||||
|
def replacer(match):
|
||||||
|
vevent = match.group(0)
|
||||||
|
if "X-MICROSOFT-CDO-BUSYSTATUS" not in vevent:
|
||||||
|
vevent = vevent.replace("\r\nEND:VEVENT", "\r\n" + injection_status + "END:VEVENT")
|
||||||
|
# Overskriv eller indsæt X-ALT-DESC
|
||||||
|
if "X-ALT-DESC" in vevent:
|
||||||
|
# Simpel håndtering: Hvis vi allerede har det, ignorer (eller implementer regex replace af X-ALT-DESC)
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
vevent = vevent.replace("\r\nEND:VEVENT", "\r\n" + injection_html + "END:VEVENT")
|
||||||
|
return vevent
|
||||||
|
|
||||||
|
text_crlf = ical_text.replace("\n", "\r\n")
|
||||||
|
vevent_pattern = re.compile(r"BEGIN:VEVENT[\s\S]*?END:VEVENT", flags=re.IGNORECASE)
|
||||||
|
return vevent_pattern.sub(replacer, text_crlf)
|
||||||
|
|
||||||
|
def create_event_ics_file(event_data, meta, log_index, total_logs, start_dt, end_dt, out_path):
|
||||||
|
title = event_data["title"]
|
||||||
|
story_text = event_data["story"]
|
||||||
|
hint = event_data.get("hint", "") # Hent hint hvis det findes
|
||||||
|
|
||||||
|
cal = Calendar()
|
||||||
|
event = Event()
|
||||||
|
event.uid = str(uuid.uuid4())
|
||||||
|
|
||||||
|
# Hvis der er et hint, sæt det evt. ind i titlen eller behold titlen ren corporate
|
||||||
|
event.name = title
|
||||||
|
event.begin = start_dt
|
||||||
|
event.end = end_dt
|
||||||
|
event.status = "CONFIRMED"
|
||||||
|
event.classification = "PUBLIC"
|
||||||
|
|
||||||
|
# Meta styling
|
||||||
|
font = meta.get("font", "Arial, sans-serif")
|
||||||
|
bg_color = meta.get("bg_color", "#f0f0f0")
|
||||||
|
text_color = meta.get("text_color", "#000000")
|
||||||
|
theme_color = meta.get("theme_color", "#000000")
|
||||||
|
log_prefix = meta.get("log_prefix", "LOG")
|
||||||
|
|
||||||
|
# Byg Header strengen
|
||||||
|
header_text = f"// {log_prefix} {log_index:02d}/{total_logs} // SUBJECT: {title.upper()}"
|
||||||
|
if hint:
|
||||||
|
header_text += f" // CODE: {hint}"
|
||||||
|
|
||||||
|
# --- HTML Version (Outlook) ---
|
||||||
|
html_desc = (
|
||||||
|
f"<div style='font-family: {font}; color: {text_color};'>"
|
||||||
|
f"<b style='color:{theme_color}'>{header_text}</b><br><br>"
|
||||||
|
f"<div style='background-color: {bg_color}; padding: 15px; border-left: 5px solid {theme_color};'>"
|
||||||
|
f"{story_text}" # Her indsætter vi story direkte, da den nu indeholder HTML tags fra JSON
|
||||||
|
f"</div><br>"
|
||||||
|
"<hr>"
|
||||||
|
"<b>OBS: Dette er en invitation til en fredagsbar.</b><br>"
|
||||||
|
"Dette event er automatisk genereret til Fredagsbar, med en title der giver Nicolaj mulighed for at deltage.<br>"
|
||||||
|
"Ingen forberedelse nødvendig.<br><br>"
|
||||||
|
"<span style='font-size: 10px; color: #666;'>"
|
||||||
|
"Vibecoded sourcecode til generering kan findes her: <a href='https://gitea.weircon.dk/{{repo}}'>gitea.weircon.dk/{{repo}}</a>"
|
||||||
|
"</span>"
|
||||||
|
"</div>"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Plain Text Version ---
|
||||||
|
# Vi erstatter <br> med \n for læsbarhed i plain text
|
||||||
|
plain_story = story_text.replace("<br>", "\n").replace("<b>", "").replace("</b>", "").replace("<i>", "").replace("</i>", "")
|
||||||
|
plain_desc = (
|
||||||
|
f"{header_text}\n\n"
|
||||||
|
f"{plain_story}\n\n"
|
||||||
|
"--------------------------------------------------\n"
|
||||||
|
"OBS: Dette er en invitation til en fredagsbar.\n"
|
||||||
|
"Ingen forberedelse nødvendig.\n"
|
||||||
|
"https://gitea.weircon.dk/{{repo}}"
|
||||||
|
)
|
||||||
|
|
||||||
|
event.description = plain_desc
|
||||||
|
cal.events.add(event)
|
||||||
|
|
||||||
|
serialized = cal.serialize()
|
||||||
|
processed = inject_outlook_lines(serialized, html_desc)
|
||||||
|
|
||||||
|
with open(out_path, "w", encoding="utf-8", newline="\r\n") as f:
|
||||||
|
f.write(processed)
|
||||||
|
|
||||||
|
print(f"[{log_index}/{total_logs}] '{title}' -> {out_path}")
|
||||||
|
|
||||||
|
def generate_series(json_path):
|
||||||
|
data = load_story(json_path)
|
||||||
|
meta = data["meta"]
|
||||||
|
events = data["events"]
|
||||||
|
|
||||||
|
story_slug = sanitize_filename(meta.get("name", "story"))
|
||||||
|
output_dir = os.path.join(OUTPUT_BASE_DIR, story_slug)
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
print(f"--- Starter generering af: {meta.get('name')} ---")
|
||||||
|
|
||||||
|
first_friday = next_or_same_friday(START_DATE)
|
||||||
|
total_logs = len(events)
|
||||||
|
|
||||||
|
for idx, event_entry in enumerate(events):
|
||||||
|
event_date = first_friday + timedelta(weeks=idx)
|
||||||
|
start_dt = datetime.combine(event_date, START_TIME).replace(tzinfo=TIMEZONE)
|
||||||
|
end_dt = start_dt + timedelta(minutes=DURATION_MINUTES)
|
||||||
|
|
||||||
|
log_num = idx + 1
|
||||||
|
|
||||||
|
# Bruger hint i filnavnet hvis det findes
|
||||||
|
hint_part = ""
|
||||||
|
if "hint" in event_entry:
|
||||||
|
hint_part = f"_{sanitize_filename(event_entry['hint'])}"
|
||||||
|
|
||||||
|
fname = f"{event_date.strftime('%Y%m%d')}_Log{log_num}{hint_part}_{sanitize_filename(event_entry['title'])}.ics"
|
||||||
|
out_path = os.path.join(output_dir, fname)
|
||||||
|
|
||||||
|
create_event_ics_file(event_entry, meta, log_num, total_logs, start_dt, end_dt, out_path)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Generer Fredagsbar ICS filer fra JSON historie.")
|
||||||
|
parser.add_argument("story_file", help="Sti til JSON filen med historien (f.eks. stories/story_scp.json)")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if not os.path.exists(args.story_file):
|
||||||
|
print(f"Fejl: Filen '{args.story_file}' findes ikke.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
generate_series(args.story_file)
|
||||||
|
print("\nFærdig!")
|
||||||
113
stories/object_87-B.json
Normal file
113
stories/object_87-B.json
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"name": "Objekt 87-B: Containment Breach",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"text_color": "#e0e0e0",
|
||||||
|
"bg_color": "#333333",
|
||||||
|
"font": "Consolas, monospace",
|
||||||
|
"organizer": "Site Administration",
|
||||||
|
"log_prefix": "LOG"
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"title": "Initialiserende Synkroniseringsmatrix",
|
||||||
|
"hint": "INITIALISERING",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Opstart af kvartalets synkronisering<br>• Kaffe og networking<br><br><b>OBSERVATION:</b><br>Jeg er ikke sikker på, hvornår jeg ankom. Kalenderen siger uge 1, men kaffen smager af <b>statisk elektricitet</b>.<br>Ledelsen insisterer på 'social kohærens'.<br><br><i>Vi mødes kl. 15. Det virker sikkert... for nu.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Tværgående Ressource-Allokering",
|
||||||
|
"hint": "DUPLIKAT",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Ressourcefordeling på tværs af teams<br><br><b>OBSERVATION:</b><br>Jeg så en kollega gå ind i mødelokale B, men han kom aldrig ud igen. I stedet kom en <b>identisk person</b> ud med et lidt andet slips.<br><br><i>Vi har brug for væske til at stabilisere nerverne og bekræfte hvem der er originaler.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Strategisk Interessent-Dialog",
|
||||||
|
"hint": "INTERFERENS",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Interessentpleje og dialog<br><br><b>OBSERVATION:</b><br>Lyden af tastaturer er stoppet i storrummet, men teksten vises stadig på skærmene af sig selv.<br><br><i>Hypotese: Hvis vi samles i grupper og indtager <b>fermenteret korn</b>, lader det til at holde skyggerne i hjørnerne på afstand.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Operationel Effektiviserings-Sprint",
|
||||||
|
"hint": "LINEARITET",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Sprint-planlægning og effektivisering<br><br><b>OBSERVATION:</b><br>Kantinen serverer i dag 'biomasse'. Jeg holder mig til flydende fødevarer efter kl. 15.00.<br><br>Det er det eneste tidspunkt på ugen, hvor <b>tidsregningen føles lineær</b> og ikke cirkulær."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Vidensdeling: Procedure 734",
|
||||||
|
"hint": "SMITTE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Vidensdeling om interne procedurer<br><br><b>OBSERVATION:</b><br>Fandt en post-it note under mit skrivebord. Der stod: '<b>Drik ikke vandet, hold dig til dåserne</b>'.<br>Jeg ved ikke, hvem der skrev det.<br><br><i>Det ligner min egen håndskrift, men blækket er stadig vådt.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Ad hoc Kapacitetsudligning",
|
||||||
|
"hint": "RESPIRATION",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Udligning af arbejdspres<br><br><b>OBSERVATION:</b><br>Luftfugtigheden stiger drastisk hver fredag eftermiddag. Det føles som om, <b>bygningen trækker vejret</b> langsommere.<br><br><i>Vi må udligne det atmosfæriske tryk internt med brusende væsker for ikke at få propper i ørerne.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Vertikal Alignment Session",
|
||||||
|
"hint": "KOLLEKTIV",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Alignment mellem ledelse og drift<br><br><b>OBSERVATION:</b><br>Ledelsen taler om 'synergi', men jeg tror, de mener '<b>hive-mind</b>'.<br><br>Alkohol synes at forstyrre signalet fra moderskibet. Vi skal drikke for at forblive individer."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Kvalitativt Review af Normalsituationen",
|
||||||
|
"hint": "GEOMETRI",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Review af driften<br><br><b>OBSERVATION:</b><br>Mødelokalerne skifter placering, når man ikke kigger. Gangene er længere end bygningen er bred.<br><br>Baren er det eneste faste holdepunkt i denne <b>ikke-euklidiske geometri</b>. Mød op for at bekræfte din lokation."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Frivillig Compliance Workshop",
|
||||||
|
"hint": "ANKER",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Workshop om compliance (frivillig)<br><br><b>OBSERVATION:</b><br>Vi har observeret fluktuationer i virkelighedsfeltet.<br>En kold øl i hånden fungerer som et <b>anker mod virkeligheden</b>.<br><br><i>Det er ikke længere en fest, det er en overlevelsesstrategi.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Human Capital Optimering",
|
||||||
|
"hint": "RESSOURCE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Optimering af human capital<br><br><b>OBSERVATION:</b><br>De kalder det 'Human Capital'. Jeg er bange for, at 'Capital' skal tages bogstaveligt som valuta.<br><br><i>Vi må bruge budgettet, før <b>budgettet bruger os</b>.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Systemisk Retrospektiv",
|
||||||
|
"hint": "ENTROPI",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Tilbageblik på systemets performance<br><br><b>OBSERVATION:</b><br>Jeg har glemt, hvad vi producerer her. Rapporter? Kode? Eller bare <b>entropi</b>?<br><br>Svaret findes muligvis i bunden af en flaske efter kl. 15, eller også glemmer man spørgsmålet."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Agil Proces-Implementering",
|
||||||
|
"hint": "HASTIGHED",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Implementering af agile principper<br><br><b>OBSERVATION:</b><br>Agilitet er nøglen. Hvis du bevæger dig hurtigt nok mod køleskabet, kan bevægelsessensorerne ikke nå at registrere din frygt.<br><br><b>Sprint review starter nu. Løb.</b>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Holistisk Værdiskabelse",
|
||||||
|
"hint": "VÅGEN",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Skabelse af værdi på tværs<br><br><b>OBSERVATION:</b><br>Værdien er skabt. Men for hvem? Enhederne i habitterne nikker bare.<br><br><i>Jeg har brug for at se et andet menneske i øjnene og skåle for at vide, at <b>jeg ikke drømmer</b>.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Strategisk Baseline-Justering",
|
||||||
|
"hint": "BASELINE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Justering af strategiske baselines<br><br><b>OBSERVATION:</b><br>Baselines flytter sig fysisk. I går var loftet grønt. I dag er det... væk?<br><br>Vi samles under de <b>kunstige lysstofrør</b> for at genoprette normaltilstanden gennem fælles konsensus."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Konsolidering af Output",
|
||||||
|
"hint": "SAFE_ZONE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Konsolidering af ugens output<br><br><b>OBSERVATION:</b><br>Outputtet lækker ud på gulvet. Der er glitch i matrixen ved kaffemaskinen.<br><br>Fredagsbaren er nu klassificeret som en <b>'Safe Zone'</b>. Søg dækning og forfriskninger øjeblikkeligt."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Skalerbarheds-analyse",
|
||||||
|
"hint": "TOMHED",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Analyse af skalerbarhed<br><br><b>OBSERVATION:</b><br>Problemet skalerer eksponentielt. Vi er nødt til at skalere vores modstandsdygtighed.<br><br>Protokollen foreskriver socialt samvær som eneste kendte modgift mod den <b>snigende tomhed</b> i gangene."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Integreret Governance Møde",
|
||||||
|
"hint": "OVERVÅGNING",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Governance og styring<br><br><b>OBSERVATION:</b><br>De observerer os gennem PowerPoints. Hvis vi lader som om, vi holder et 'møde' med øl, lader de os være i fred.<br><br><b>Spil med.</b> For din egen skyld. Nik og smil."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Afsluttende KPI-Opfølgning",
|
||||||
|
"hint": "ATMOSFÆRE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Opfølgning på KPI'er<br><br><b>OBSERVATION:</b><br>KPI: 'Keep Panic Inside'. Det lykkes bedst med en promille over 0.<br><br>Det er næsten slut nu. Jeg kan mærke en <b>ændring i atmosfærens kemiske sammensætning</b>."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Exit Strategy Formulering",
|
||||||
|
"hint": "INGEN_UDGANG",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Formulering af exit-strategier<br><br><b>OBSERVATION:</b><br>Der er ingen udgang. <b>Døren i receptionen er blot et maleri på væggen</b>.<br><br>Men så længe der er fredagsbar, er vi i det mindste fanget sammen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Total System Reboot",
|
||||||
|
"hint": "GENSTART",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Systemvedligeholdelse<br><br><b>OBSERVATION:</b><br>Cyklussen er komplet. Hukommelsen vil blive slettet mandag morgen.<br><br><i>Nyd denne sidste stund af klarhed. <b>Vi ses på den anden side af genstarten.</b></i>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
113
stories/sagen_om_konsulent_n.json
Normal file
113
stories/sagen_om_konsulent_n.json
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"name": "Sagen om Konsulent N.",
|
||||||
|
"theme_color": "#b30000",
|
||||||
|
"text_color": "#1a1a1a",
|
||||||
|
"bg_color": "#fff5f5",
|
||||||
|
"font": "Courier New, monospace",
|
||||||
|
"organizer": "Internal Audit / Shadow IT",
|
||||||
|
"log_prefix": "CASE FILE"
|
||||||
|
},
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"title": "Ugentlig tværgående synkronisering",
|
||||||
|
"hint": "AFVIGELSE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Hurtig synk af ugens løse ender<br>• Ingen forberedelse nødvendig (seriøst)<br><br><b>FORTROLIGT UDDRAG:</b><br>Vi har en afvigelse i kalenderdomænet. Konsulent “N.” har stået som *OPTAGET* siden sidste fredag.<br>Der findes ingen mødeindkaldelse i historikken — kun en gentagelse.<br><br><i>Bemærkning:<br>Hvis du hører Outlook-påmindelsen uden at have en påmindelse: ignorer den, og mød op alligevel.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Obligatorisk sjov",
|
||||||
|
"hint": "BADGE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• “Teambuilding” uden slide deck<br>• Interessentpleje (humør)<br><br><b>FORTROLIGT UDDRAG:</b><br>Receptionen fandt et adgangskort med teksten: “KONSULENT N.” på gulvet ved køleskabet.<br>Kortet var lunt, som om det lige var blevet brugt — men ingen har registreret adgang.<br><br><i>Til stedeværende anbefales:<br>Smil normalt. Lad være med at sige ordet “gentagelse” højt før kl. 15:05.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Afsluttende statusmøde (uformelt)",
|
||||||
|
"hint": "SIGNAL",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Uformel status og weekendoverdragelse<br>• Opsamling på “wins”<br><br><b>FORTROLIGT UDDRAG:</b><br>Kl. 15:00 præcis kom der et systemevent:<br>“Your meeting has been updated.”<br>Ingen opdaterede noget.<br><br>Kort efter: en enkelt linje i beskrivelsesfeltet (nu slettet):<br><i>“…jeg kan høre isterningerne, men jeg kan ikke nå dem.”</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Kvalitativ erfaringsudveksling",
|
||||||
|
"hint": "NOTE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Del en ting der virkede denne uge<br>• Del en ting der ikke gjorde<br><br><b>FORTROLIGT UDDRAG:</b><br>Der cirkulerer en printet mødeagenda med håndskrift nederst:<br><br>“Hvis I læser dette, så er jeg ikke forsvundet.<br>Jeg er bare blevet flyttet til et lokale, der kun findes om fredagen.”<br><br>Papiret lugter af citrus og… mødelokale-tæppe."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Strategisk afrunding af arbejdsugen",
|
||||||
|
"hint": "INDDÆMNING",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Strategisk afrunding (aka: “god weekend”)<br><br><b>FORTROLIGT UDDRAG:</b><br>IT har forsøgt at “aflyse serien”.<br>Kalenderen genopretter den inden for 9 sekunder.<br><br><b>Foreløbig inddæmningsprocedure:</b><br>• Indkaldelsen må ikke slettes<br>• Deltagere skal møde fysisk op<br>• Der må gerne medbringes snacks (observationsmæssigt stabiliserende)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Tværfaglig alignment-session",
|
||||||
|
"hint": "STØTTE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Let alignment på tværs (ingen action items)<br><br><b>FORTROLIGT UDDRAG:</b><br>HR, IT og Facilities blev spurgt, om der findes et “Mødelokale 4B (uofficielt)”.<br>Facilities svarede: “Det gør der ikke.”<br>Så tilføjede de: “Men døren står nogle gange på klem om fredagen.”<br><br><i>Anbefaling:<br>Kom som du er. Tag evt. en ekstra ven med. (Flere vidner = færre glitch).</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Ad hoc interessentdialog",
|
||||||
|
"hint": "KØLESKAB",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Løst og socialt touchpoint<br><br><b>FORTROLIGT UDDRAG:</b><br>Ny interessent identificeret: Køleskabet.<br>Det afgiver en svag brummen i en rytme, der minder om en mødepåmindelse.<br><br>Ved forsøg på åbning kl. 14:59:<br>• håndtag koldt<br>• håndtag “giver sig” først efter en skål<br><br>Hypotese:<br>Køleskabet reagerer på ritualiseret fredagsbar-adfærd."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Intern kapacitetsudligning",
|
||||||
|
"hint": "KAPACITET",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Afbalancering af ugens energiniveau<br><br><b>FORTROLIGT UDDRAG:</b><br>Vi har brug for kapacitetsplanlægning:<br>• 1 person: isterninger<br>• 1 person: musik<br>• 1 person: “spørg ikke hvorfor, bare gør det” (koordinator)<br><br>Konsulent N. er muligvis låst til en times varighed ad gangen.<br>Hvis nogen forlader før tid, bliver rummet… mindre."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Letvægts-retrospektiv",
|
||||||
|
"hint": "RETRO",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Hvad skal vi gøre mere af? Mindre af?<br><br><b>FORTROLIGT UDDRAG:</b><br>Root cause er sandsynligvis denne handling:<br>Konsulent N. trykkede “Accepter alle forekomster” uden at læse beskrivelsen.<br><br>Der findes nu en gentagende mødeserie, som opfører sig som en beholder.<br>Og N. er “i mødet” — ikke i bygningen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Uformel leverancegennemgang",
|
||||||
|
"hint": "NØGLE",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Gennemgang af ugens “leverancer” (uformelt)<br><br><b>FORTROLIGT UDDRAG:</b><br>Lost & Found indeholdt én genstand, der ikke burde være der:<br>En nøgle mærket “FB-LOKAL” i en plastikpose.<br>Posen var dateret næste fredag.<br><br><i>Bemærkning:<br>Tid opfører sig dårligt i nærheden af serien.<br>Vi tester nøglen ved første skål.</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Operationel efterbearbejdning",
|
||||||
|
"hint": "EKKO",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Efterbearbejdning af ugen (lavt gear)<br><br><b>FORTROLIGT UDDRAG:</b><br>Når glas rammer glas, kommer der et ekko, der ikke passer til rummet.<br>Ekkoet lyder som nogen der prøver at sige:<br><i>“…er I her…?”</i><br><br>Hvis du hører ekkoet:<br>Svar ikke direkte. Skål bare igen. (Det virker mere stabilt)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Tværorganisatorisk vidensdeling",
|
||||||
|
"hint": "SITES",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Vidensdeling (uformel)<br><br><b>FORTROLIGT UDDRAG:</b><br>Andre kontorer rapporterer lignende:<br>“En fredagsbar-invite der bliver ved med at vende tilbage.”<br>De kalder det: “Den Tilbagevendende Invitation”.<br><br>Fælles observation:<br>Når folk møder op og hygger, falder antallet af fejl i kalenderen midlertidigt."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Kalibreringsmøde (lav intensitet)",
|
||||||
|
"hint": "TÆRSKEL",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Kalibrering uden intensitet<br><br><b>FORTROLIGT UDDRAG:</b><br>Kalibreringsparameter fundet:<br>Temperatur.<br>Hvis køleskabet når præcis “fredagskoldt”, bliver lyden i rummet klarere.<br><br><b>Strengt forbudt:</b><br>0,0% øl omtalt som “sikkert alternativ”.<br>Det gjorde rummet… meget stille sidst."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Afrunding af ugens initiativer",
|
||||||
|
"hint": "ÅBNING",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Afrunding af igangværende initiativer<br><br><b>FORTROLIGT UDDRAG:</b><br>Nøglen passer i en dør, der normalt ikke har nøglehul.<br>Døren dukker op bag kaffemaskinen præcis 15:02.<br><br>På den anden side:<br>Et lokale med projektor.<br>Projektoren viser kun én slide:<br>“STATUS: OPTAGET”"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Intern koordinering uden agenda",
|
||||||
|
"hint": "STILHED",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Koordinering uden agenda<br><br><b>FORTROLIGT UDDRAG:</b><br>Vi opdagede at en agenda gør det værre.<br>Når nogen skriver “Agenda:” i rummet, forsvinder døren igen.<br><br>Så:<br>• Ingen agenda<br>• Ingen referat<br>• Ingen action items<br>Kun fredagsbar.<br><br>(Det føles næsten for corporate til at virke. Men det virker.)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Eksperimentel samarbejdsramme",
|
||||||
|
"hint": "RITUAL",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Eksperimentel ramme (aka: prøv noget)<br><br><b>FORTROLIGT UDDRAG:</b><br>Nyt retrieval-eksperiment:<br>Kl. 15:07 foretages en synkroniseret skål.<br>Efterfulgt af: “God weekend” sagt én gang — ikke to.<br><br>Da vi testede det, kom der en notifikation:<br><i>“Konsulent N. forsøger at deltage.”</i>"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Socialt orienteret statusafstemning",
|
||||||
|
"hint": "PULS",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Social statusafstemning (hvordan går det egentlig?)<br><br><b>FORTROLIGT UDDRAG:</b><br>Lyden fra “mødelokalet på den anden side” har nu en puls.<br>Den synker, når nogen griner.<br>Den stiger, når nogen siger “lige hurtigt”.<br><br>Vi kan muligvis trække N. tættere på ved at gøre rummet… menneskeligt."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Procesmæssig nedlukning af ugen",
|
||||||
|
"hint": "PORTAL",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Luk ugen ned på den rigtige måde<br><br><b>FORTROLIGT UDDRAG:</b><br>Portalen er stabil i cirka 58 minutter.<br>Ved 59:30 begynder projektoren at vise “MØDET ER FORLÆNGET”.<br><br>Hvis vi ikke lukker rigtigt:<br>Serien udvider sig med et ekstra “opfølgningsmøde”.<br>Ingen ønsker et follow-up til fredagsbar. Ingen."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Konsensusbaseret afrunding",
|
||||||
|
"hint": "BESLUTNING",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Konsensusbaseret afrunding (enighed + hygge)<br><br><b>FORTROLIGT UDDRAG:</b><br>Vi skal beslutte:<br>Åbner vi køleskabet helt?<br><br>Sidste gang blev døren på klem, og en hånd (med et tastatur-mærke) nåede ud.<br>Den slap en Post-it:<br>“Jeg er her. Jeg er stadig optaget.”<br><br>Konsensus kræver tilstedeværelse. (Og måske chips)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Frivillig deltagelse i fælles kontekst",
|
||||||
|
"hint": "HJEMKOMST",
|
||||||
|
"story": "<b>OFFICIELT FORMÅL:</b><br>• Frivillig deltagelse, fælles kontekst, afslappet<br><br><b>FORTROLIGT UDDRAG:</b><br>Hvis retrieval lykkes, vil N. fremstå normal.<br>Undtagen:<br>• Hans Outlook vil muligvis vise 1900 ulæste reminders<br>• Han vil reagere på ordet “gentagelse” som på en høj lyd<br><br><i>Afsluttende note (fra N., modtaget som kalenderopdatering):<br>“Tak. Bliv ved med at møde op. Det er sådan man holder virkeligheden på plads om fredagen.”</i>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user