diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..2f5b48d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Review for this repo routes to the Agentic Runtime working-group leads. +# See: https://github.com/cloudfoundry/community/blob/main/toc/working-groups/agentic-runtime.md +* @beyhan @wayneeseguin @rkoster @itsouvalas diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..52486ef --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,15 @@ + + +## What is this note about? + + + +## Checklist + +- [ ] My note lives in `research/` and uses a lowercase kebab-case filename. +- [ ] It starts from `research/TEMPLATE.md` and has valid frontmatter + (`title`, `author`, `date`, `tags`, `status`, `sources`). +- [ ] It has the four sections: Summary, Key findings, CF relevance, Open questions. +- [ ] I added relevant `tags` (see the suggested vocabulary in `IDEATION.md`). +- [ ] Sources are linked. +- [ ] It's on-topic for agentic workloads on Cloud Foundry diff --git a/.github/scripts/validate_notes.py b/.github/scripts/validate_notes.py new file mode 100644 index 0000000..107abcf --- /dev/null +++ b/.github/scripts/validate_notes.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python3 +"""Validate research notes in research/ and ideas in ideas/. + +For every research/*.md file except README.md and TEMPLATE.md this checks: + - the filename is lowercase kebab-case ending in .md + - a YAML frontmatter block is present and parses + - required frontmatter keys are present and well-typed + - the four required body section headings are present + +Ideas are deliberately low-barrier. For every ideas/*.md file except README.md and +TEMPLATE.md this checks only: + - the filename is lowercase kebab-case ending in .md + - a title is present (a YAML 'title:' or a '# ' heading) + +Exits non-zero (printing every problem) if any note or idea is invalid. +""" + +from __future__ import annotations + +import datetime as dt +import pathlib +import re +import sys + +import yaml + +RESEARCH_DIR = pathlib.Path("research") +IDEAS_DIR = pathlib.Path("ideas") +SKIP = {"README.md", "TEMPLATE.md"} + +REQUIRED_KEYS = { + "title": str, + "author": str, + "date": object, # validated separately + "tags": list, + "status": str, + "sources": list, +} +ALLOWED_STATUS = {"draft", "reviewed"} +REQUIRED_SECTIONS = [ + "## Summary", + "## Key findings", + "## CF relevance", + "## Open questions", +] +FILENAME_RE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*\.md$") +FRONTMATTER_RE = re.compile(r"^---\n(.*?)\n---\n", re.DOTALL) +DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$") +H1_RE = re.compile(r"^#\s+\S", re.MULTILINE) + + +def validate_file(path: pathlib.Path) -> list[str]: + problems: list[str] = [] + name = path.name + + if not FILENAME_RE.match(name): + problems.append( + f"filename must be lowercase kebab-case ending in .md (got '{name}')" + ) + + text = path.read_text(encoding="utf-8") + + match = FRONTMATTER_RE.match(text) + if not match: + problems.append("missing YAML frontmatter block (must start with '---' on line 1)") + return [f"{path}: {p}" for p in problems] + + try: + meta = yaml.safe_load(match.group(1)) + except yaml.YAMLError as exc: + problems.append(f"frontmatter is not valid YAML: {exc}") + return [f"{path}: {p}" for p in problems] + + if not isinstance(meta, dict): + problems.append("frontmatter must be a YAML mapping") + return [f"{path}: {p}" for p in problems] + + for key, expected_type in REQUIRED_KEYS.items(): + value = meta.get(key) + if value in (None, "", [], {}): + problems.append(f"missing required frontmatter key '{key}'") + continue + if expected_type is not object and not isinstance(value, expected_type): + problems.append(f"frontmatter key '{key}' must be a {expected_type.__name__}") + + status = meta.get("status") + if isinstance(status, str) and status not in ALLOWED_STATUS: + problems.append( + f"'status' must be one of {sorted(ALLOWED_STATUS)} (got '{status}')" + ) + + date_val = meta.get("date") + if date_val not in (None, "", [], {}): + if isinstance(date_val, dt.date): + pass # YAML already parsed a date + elif isinstance(date_val, str) and DATE_RE.match(date_val): + pass + else: + problems.append("'date' must be in YYYY-MM-DD format") + + body = text[match.end():] + for section in REQUIRED_SECTIONS: + if not re.search(rf"^{re.escape(section)}\s*$", body, re.MULTILINE): + problems.append(f"missing required section heading '{section}'") + + return [f"{path}: {p}" for p in problems] + + +def validate_idea(path: pathlib.Path) -> list[str]: + """Light validation: kebab-case filename plus a title of some kind.""" + problems: list[str] = [] + name = path.name + + if not FILENAME_RE.match(name): + problems.append( + f"filename must be lowercase kebab-case ending in .md (got '{name}')" + ) + + text = path.read_text(encoding="utf-8") + + has_title = False + body = text + match = FRONTMATTER_RE.match(text) + if match: + body = text[match.end():] + try: + meta = yaml.safe_load(match.group(1)) + except yaml.YAMLError as exc: + problems.append(f"frontmatter is not valid YAML: {exc}") + else: + if isinstance(meta, dict) and str(meta.get("title") or "").strip(): + has_title = True + + if not has_title and not H1_RE.search(body): + problems.append("idea needs a title (a YAML 'title:' or a '# ' heading)") + + return [f"{path}: {p}" for p in problems] + + +def main() -> int: + if not RESEARCH_DIR.is_dir(): + print(f"error: '{RESEARCH_DIR}/' directory not found", file=sys.stderr) + return 1 + + notes = sorted(p for p in RESEARCH_DIR.glob("*.md") if p.name not in SKIP) + ideas = ( + sorted(p for p in IDEAS_DIR.glob("*.md") if p.name not in SKIP) + if IDEAS_DIR.is_dir() + else [] + ) + + problems: list[str] = [] + for note in notes: + problems.extend(validate_file(note)) + for idea in ideas: + problems.extend(validate_idea(idea)) + + if problems: + print("Validation failed:\n") + for problem in problems: + print(f" - {problem}") + print( + f"\n{len(problems)} problem(s) across " + f"{len(notes)} research note(s) and {len(ideas)} idea(s)." + ) + return 1 + + print(f"OK: {len(notes)} research note(s) and {len(ideas)} idea(s) valid.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..cd1790a --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,34 @@ +name: Validate notes and ideas + +on: + pull_request: + paths: + - "research/**" + - "ideas/**" + - ".github/scripts/validate_notes.py" + - ".github/workflows/lint.yml" + push: + branches: [main] + paths: + - "research/**" + - "ideas/**" + - ".github/scripts/validate_notes.py" + - ".github/workflows/lint.yml" + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Check out + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install dependencies + run: pip install "pyyaml>=6" + + - name: Validate notes and ideas + run: python .github/scripts/validate_notes.py diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..62bae26 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,13 @@ +# Code of Conduct + +The Cloud Foundry Agentic Runtime Working Group, like all Cloud Foundry community spaces, +operates under the **Cloud Foundry Foundation Code of Conduct**. + +Please read it here: https://www.cloudfoundry.org/code-of-conduct/ + +By participating in this repository — through issues, pull requests, reviews, or any other +interaction — you agree to abide by its terms. + +To report a concern, follow the reporting instructions in the linked Code of Conduct, or +reach a working-group lead in [#ai-wg](https://cloudfoundry.slack.com/archives/C0B214KJ1HA) +on the Cloud Foundry Slack. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7a17abb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,77 @@ +# Contributing + +Thanks for helping shape the future of agentic workloads on Cloud Foundry. During the +current **research phase** there are two ways to contribute, both via pull request: + +- A quick **idea** in [`ideas/`](./ideas) — low bar, no sourcing required. A place for + sparks, so nothing gets turned away for not yet being a full research note. +- A sourced **research note** in [`research/`](./research) — structured and cited. + +Ideas and research link together: an idea points to the research that backs it, and one +research note can back several ideas. An idea with enough research behind it can later become +a proposal. + +For the why and the bigger picture, read [`IDEATION.md`](./IDEATION.md). + +## Adding an idea + +Copy [`ideas/TEMPLATE.md`](./ideas/TEMPLATE.md) to `ideas/my-idea.md`, jot down the spark, +and open a PR. The only hard rules are a kebab-case filename and a title — everything else +is optional. See [`ideas/README.md`](./ideas/README.md). + +## Adding a research note + +1. **Fork** this repository (or, if you're a working-group member with write access, create + a branch). +2. **Copy the template:** + ```bash + cp research/TEMPLATE.md research/my-topic.md + ``` +3. **Fill it in.** Keep it short, sourced, and outward-looking (see + [`IDEATION.md`](./IDEATION.md) for what Phase 1 is after). See + [`research/README.md`](./research/README.md) for the frontmatter schema. +4. **Commit your note:** + ```bash + git add research/my-topic.md + git commit -m "Add research note: my topic" + ``` +5. **Open a pull request.** A CI check validates your note's frontmatter and structure. A + working-group tech lead will give it a quick look and merge. + +## Filename convention + +- Lowercase **kebab-case**, ending in `.md`: `research/agent-frameworks.md`. +- If your topic collides with an existing note, add your GitHub handle as a suffix: + `research/agent-frameworks-rkoster.md`. + +## Frontmatter + +Every note starts with a YAML frontmatter block. Required keys: `title`, `author`, `date`, +`tags`, `status`, `sources`. The `cf_areas` key is optional. The full schema and field +descriptions live in [`research/README.md`](./research/README.md). + +Tagging well matters — tags are how the workshop clusters notes into themes. See the +suggested (non-binding) vocabulary in +[`IDEATION.md`](./IDEATION.md#tagging-how-themes-will-emerge). + +## Review & merge + +Research notes are low-risk, so we optimize for throughput: + +- For research notes, CI validates frontmatter, filename, and required sections. For + [`ideas/`](./ideas) it only checks the filename and that a title is present. +- Any working-group **tech lead** can merge once CI passes and the contribution is on-topic. +- Substantive debate about the *merits* of a contribution happens at the workshop, not as a + merge gate. + +## Contributor License Agreement (CLA) + +All committers to a Cloud Foundry Foundation project must sign a Contributor License +Agreement. You don't need to do anything up front: the **EasyCLA** bot comments on your +first pull request with a link to sign (individual or corporate). Once it's signed, the +CLA check goes green and your PR can be merged. You can also +[sign in to EasyCLA](https://corporate.v1.easycla.lfx.linuxfoundation.org/) ahead of time. + +## Code of conduct + +This project follows the [Cloud Foundry Code of Conduct](./CODE_OF_CONDUCT.md). diff --git a/IDEATION.md b/IDEATION.md new file mode 100644 index 0000000..9729b0e --- /dev/null +++ b/IDEATION.md @@ -0,0 +1,119 @@ +# Ideation Brief — Agentic Runtime Research Phase + +**Status:** Proposed (this brief is itself under review — feedback welcome on the PR). +**Working group:** [Cloud Foundry Agentic Runtime](https://github.com/cloudfoundry/community/blob/main/toc/working-groups/agentic-runtime.md) + +## Why this phase exists + +The Agentic Runtime Working Group is new, and the design space — running AI agents and +LLM-powered workloads as first-class citizens on Cloud Foundry — is broad and moving fast. +Before committing to specific designs or RFCs, we want to map the landscape together: +gather what the community already knows and surface prior art from the wider ecosystem. +With that map in hand, the workshop can then see where Cloud Foundry's primitives help or +fall short. + +This repository is the home for that research. It is deliberately **lightweight and +open**: the goal is breadth of input from anyone interested, not polished deliverables. + +## The four-phase roadmap + +This research phase is step one of four: + +1. **Capture & research (now, ~a few weeks).** Contributors open pull requests with either + a quick **idea** in [`ideas/`](./ideas) — a spark, question, or pointer, at a low bar — + or a short, sourced **research note** in [`research/`](./research). We want broad, + *outward-looking* coverage of the wider agentic ecosystem — relevant technologies, prior + art, and how others solve these problems. Where Cloud Foundry fits comes later. Ideas and + research link together — one research note can back several ideas — and an idea with enough + research behind it can grow into a proposal. +2. **Workshop.** The working group meets to read across the accumulated notes and cluster + them into **themes**. Themes are *not* defined up front — they emerge from what people + actually contribute. +3. **Match.** Working-group members align their interests with the identified themes and + form small groups around them. +4. **POC / RFC.** Each theme group spins up focused work — proofs-of-concept and Cloud + Foundry RFCs — feeding the platform roadmap. + +We are building only what Phase 1 needs right now. Structure for themes, POCs, and RFCs +will be added once the workshop has shaped it. + +## What to contribute in Phase 1 + +**Look outward.** Phase 1 is about understanding the wider agentic and AI ecosystem — not +about cataloguing Cloud Foundry. Where Cloud Foundry's primitives help or fall short is +something we want to *discover* at the workshop, drawn from this research, rather than +assume up front. + +**Two ways in.** Not everything needs to be a polished note. If you have a spark but no +time to write it up, drop it in [`ideas/`](./ideas) — we'd rather capture it than turn it +away for not being a full research note. A sourced, structured write-up belongs in +[`research/`](./research). The scope below applies to both. + +**In scope** — research notes that inform the design space, such as: + +- Analyses of agent frameworks, protocols, and platforms (how others solve a problem). +- Prior art and standards — identity, sandboxing, observability, orchestration conventions. +- How adjacent runtimes and platforms (Kubernetes, serverless, other PaaS) handle agentic + workloads. +- Surveys of the surrounding ecosystem and where it's heading. + +**Out of scope for now:** + +- Finished solutions, designs, or RFCs — those come in Phase 4, after the workshop. A note + may *raise* questions and point at possible directions, but its job is to inform, not to + settle on a final answer. +- Definitive Cloud Foundry gap lists. Identifying gaps is an **outcome** of this phase, + synthesized at the workshop from the body of research — not a starting point any one + contributor supplies. + +## What makes a good research note + +- **Sourced.** Link to the primary material so others can dig in. +- **Summarized.** A few sentences capturing the essence — assume the reader is busy. +- **Outward-looking, with a light CF lens.** The substance is the external research; add a + short note on why it might matter for Cloud Foundry. A loose or speculative connection is + fine — "not sure how this maps yet" is a perfectly good answer. +- **Honest about open questions.** Unknowns are valuable signal for the workshop. + +Each note follows a small template — see [`research/TEMPLATE.md`](./research/TEMPLATE.md). +[`CONTRIBUTING.md`](./CONTRIBUTING.md) explains the mechanics. + +## Tagging: how themes will emerge + +Each note carries free-form `tags` in its frontmatter. At the workshop we'll use these +tags to cluster notes into themes — so tagging well is how you influence the agenda. + +Tags are **descriptive, not prescriptive.** To reduce noise, here is a *non-binding* +starting vocabulary drawn from the working-group charter. Use these where they fit, and +invent new ones where they don't: + +- `identity` — workload/agent identity, authn, authz +- `runtime-lifecycle` — how agents are deployed, started, stopped, resumed +- `sandboxing-isolation` — execution isolation, policy enforcement +- `orchestration` — multi-step / multi-agent coordination +- `inter-agent-comms` — agent-to-agent and agent-to-tool protocols +- `observability-governance` — telemetry, audit, compliance +- `autoscaling` — event-driven and scale-to-zero patterns +- `ecosystem-survey` — landscape scans of tools, frameworks, vendors + +**These are hints, not buckets.** Don't file your note into a predetermined theme — just +describe it accurately and let the themes emerge. + +## Timeline + +Specific dates (the research window length and the workshop date) are set at the +working-group kickoff and announced in +[#ai-wg](https://cloudfoundry.slack.com/archives/C0B214KJ1HA) on Slack. Expect the research +window to run a few weeks. + +## How to participate + +1. Read [`CONTRIBUTING.md`](./CONTRIBUTING.md). +2. Add an idea or a research note using the matching template, and open a PR. +3. Join the conversation in [#ai-wg](https://cloudfoundry.slack.com/archives/C0B214KJ1HA). + +## Feedback on this process + +This brief is part of the first pull request *on purpose* — so the working group can shape +the process before research arrives at volume. If something here doesn't serve the goal, +say so on the PR. diff --git a/README.md b/README.md new file mode 100644 index 0000000..16619e8 --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# Agentic Runtime — Working Group Notes + +> **Status: Phase 1 of 4 — Research (open for contributions).** +> This repository is in its initial ideation/research phase. The process described below +> is itself under review — see [`IDEATION.md`](./IDEATION.md) and please leave feedback on +> the pull request that introduces it. + +Research notes, design documents, and RFCs for the Cloud Foundry +[**Agentic Runtime Working Group**](https://github.com/cloudfoundry/community/blob/main/toc/working-groups/agentic-runtime.md). + +The working group's mission is to run AI agents and LLM-powered workloads as first-class +citizens on Cloud Foundry — deployed, managed, secured, scaled, and observed using the +same platform-native primitives developers and operators rely on today. + +## What this repo is for + +This repo bootstraps a **crowd-sourced, distributed research phase**. Anyone interested in +the future of agentic workloads on Cloud Foundry is invited to contribute — either a quick +**idea** in [`ideas/`](./ideas) or a sourced **research note** in [`research/`](./research), +both as pull requests. The accumulated material becomes the raw input for a working-group +workshop that identifies themes and spins up focused proof-of-concept and RFC work. + +## The roadmap + +Contributions come in two linked lanes — raw **ideas** and the sourced **research** that +backs them. Research is reusable, so one note can support several ideas, and an idea with +enough research behind it can grow into a **proposal** later on: + +1. **Capture & research (now)** — drop a spark in [`ideas/`](./ideas) or a sourced note in + [`research/`](./research), via PRs. +2. **Workshop** — the working group clusters the material into emergent themes. +3. **Match** — members align their interests to themes. +4. **POC / RFC** — per-theme tracks produce proofs-of-concept and Cloud Foundry RFCs. + +See [`IDEATION.md`](./IDEATION.md) for the full brief. + +## How to contribute + +Two ways in, both via pull request: + +- **Have a quick idea?** Drop a short note in [`ideas/`](./ideas) — low bar, no sourcing + required. We'd rather capture it than turn it away for not being a full research note. +- **Ready to write it up?** Copy [`research/TEMPLATE.md`](./research/TEMPLATE.md), fill it + in, and add it to [`research/`](./research). + +Read [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the workflow. In this phase we're especially +interested in research that looks **outward** at the wider agentic ecosystem — see +[`IDEATION.md`](./IDEATION.md) for scope. + +## Community + +- **Charter:** [toc/working-groups/agentic-runtime.md](https://github.com/cloudfoundry/community/blob/main/toc/working-groups/agentic-runtime.md) +- **Slack:** [#ai-wg](https://cloudfoundry.slack.com/archives/C0B214KJ1HA) on the Cloud Foundry workspace +- **Working groups:** [cloudfoundry/community](https://github.com/cloudfoundry/community/blob/main/toc/working-groups/WORKING-GROUPS.md) + +## License + +Apache 2.0 — see [`LICENSE`](./LICENSE). By contributing you agree to the Cloud Foundry +[Contributor License Agreement](https://github.com/cloudfoundry/community/blob/main/CONTRIBUTING.md). +You don't need to do anything up front — the [EasyCLA](https://corporate.v1.easycla.lfx.linuxfoundation.org/) +bot prompts you to sign on your first pull request. diff --git a/ideas/README.md b/ideas/README.md new file mode 100644 index 0000000..212fec7 --- /dev/null +++ b/ideas/README.md @@ -0,0 +1,30 @@ +# Ideas + +A low-barrier place for **sparks** — a question, a hunch, a link you haven't written up, +or a "someone should look into this." If it isn't ready to be a full +[research note](../research), it belongs here. We'd rather capture an idea than turn it +away for not being polished. + +Ideas are the front of the funnel. As an idea gathers supporting research it firms up and +feeds the workshop — and an idea with enough research behind it can grow into a proposal. + +## What belongs here + +- A topic worth researching, with a sentence on why. +- An open question about agentic workloads, runtimes, or the surrounding ecosystem. +- A pointer to something interesting — a project, paper, or protocol — you haven't + summarized yet. + +Anything more developed — sourced and structured — is a [research note](../research) +instead. Not sure which it is? Start here; it can graduate later. + +## Adding an idea + +Copy [`TEMPLATE.md`](./TEMPLATE.md) to a kebab-case filename (`my-idea.md`) and jot it +down. The only hard rules are a **kebab-case filename** and a **title** (a YAML `title:` +or a `# ` heading) — everything else is optional. Tags help the workshop cluster ideas, +so add them if you can. + +Link the research that backs your idea under **Related** so others can follow the trail. The +same research note can back more than one idea, so link it even if it already appears +elsewhere. diff --git a/ideas/TEMPLATE.md b/ideas/TEMPLATE.md new file mode 100644 index 0000000..b5140f0 --- /dev/null +++ b/ideas/TEMPLATE.md @@ -0,0 +1,28 @@ +--- +title: +author: (@your-github-handle) +date: 2026-01-01 +tags: [] +--- + + + +## The idea + + + +## Why it might matter + + + +## What to research next + + + +## Related + + diff --git a/research/README.md b/research/README.md new file mode 100644 index 0000000..81cbdd5 --- /dev/null +++ b/research/README.md @@ -0,0 +1,72 @@ +# Research notes + +This directory holds the working group's research notes for the current research phase +(see [`../IDEATION.md`](../IDEATION.md)). + +The directory is intentionally **flat**: every note is a single Markdown file here, with +metadata in YAML frontmatter. We do **not** sort notes into topic folders — themes are +identified later, at the workshop, by clustering on tags. Filing notes into folders now +would pre-impose the very themes we want to let emerge. + +## Adding a note + +Copy [`TEMPLATE.md`](./TEMPLATE.md), rename it to a kebab-case topic (`my-topic.md`), and +fill it in. See [`../CONTRIBUTING.md`](../CONTRIBUTING.md) for the full workflow. + +Not ready for a sourced write-up? Drop a spark in [`../ideas/`](../ideas) instead — it can +graduate into a research note later. + +## Frontmatter schema + +Each note begins with a YAML frontmatter block: + +```yaml +--- +title: How LangGraph models multi-agent orchestration +author: Jane Doe (@janedoe) +date: 2026-06-25 +tags: [orchestration, inter-agent-comms, ecosystem-survey] +cf_areas: [diego, capi] +status: draft +sources: + - https://example.com/source-one +--- +``` + +| Field | Required | Description | +|-------|----------|-------------| +| `title` | yes | Concise human-readable title. | +| `author` | yes | `Name (@github-handle)`. | +| `date` | yes | `YYYY-MM-DD`, the date the note was written. | +| `tags` | yes | List of free-form tags. Drives theme clustering — see the suggested vocabulary in [`../IDEATION.md`](../IDEATION.md#tagging-how-themes-will-emerge). | +| `cf_areas` | no | List of related Cloud Foundry components (e.g. `diego`, `capi`, `uaa`, `bosh`, `loggregator`). | +| `status` | yes | `draft` or `reviewed`. | +| `sources` | yes | List of URLs to the primary material. | + +## Body structure + +After the frontmatter, use these four sections: + +```markdown +## Summary + +Two to four sentences capturing the essence. + +## Key findings + +- Bullet points with the substantive takeaways. + +## CF relevance + +A short, light-touch note on why this might matter for Cloud Foundry. A loose or +speculative connection is fine — including "not sure how this maps yet." Synthesizing the +research into concrete Cloud Foundry gaps is the workshop's job, not something each note +has to settle. + +## Open questions + +- Unresolved questions worth raising at the workshop. +``` + +A CI check validates that every note has valid frontmatter, a kebab-case filename, and +these four sections. diff --git a/research/TEMPLATE.md b/research/TEMPLATE.md new file mode 100644 index 0000000..3b457b9 --- /dev/null +++ b/research/TEMPLATE.md @@ -0,0 +1,33 @@ +--- +title: +author: (@your-github-handle) +date: 2026-01-01 +tags: [, ] +cf_areas: [] +status: draft +sources: + - +--- + + + +## Summary + + + +## Key findings + +- + +## CF relevance + + + +## Open questions + +-