projectstore-codex 0.0.1 → 0.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +48 -0
- package/README.md +15 -7
- package/bin/projectstore-codex.mjs +88 -0
- package/hooks/hooks.json +59 -0
- package/node_modules/projectstore/.claude-plugin/marketplace.json +40 -0
- package/node_modules/projectstore/.claude-plugin/plugin.json +23 -0
- package/node_modules/projectstore/.mcp.json +14 -0
- package/node_modules/projectstore/AGENTS.md +26 -0
- package/node_modules/projectstore/LICENSE +21 -0
- package/node_modules/projectstore/README.md +284 -0
- package/node_modules/projectstore/agents/archaeologist.md +76 -0
- package/node_modules/projectstore/agents/clerk.md +93 -0
- package/node_modules/projectstore/agents/critic.md +94 -0
- package/node_modules/projectstore/agents/librarian.md +81 -0
- package/node_modules/projectstore/agents/planner.md +80 -0
- package/node_modules/projectstore/agents/reviewer.md +98 -0
- package/node_modules/projectstore/bin/projectstore.mjs +7 -0
- package/node_modules/projectstore/commands/adr.md +57 -0
- package/node_modules/projectstore/commands/agents.md +180 -0
- package/node_modules/projectstore/commands/bind.md +128 -0
- package/node_modules/projectstore/commands/codemap.md +50 -0
- package/node_modules/projectstore/commands/concept.md +17 -0
- package/node_modules/projectstore/commands/doctor.md +166 -0
- package/node_modules/projectstore/commands/epic.md +40 -0
- package/node_modules/projectstore/commands/graph.md +56 -0
- package/node_modules/projectstore/commands/kanban.md +40 -0
- package/node_modules/projectstore/commands/meeting.md +17 -0
- package/node_modules/projectstore/commands/reconcile.md +73 -0
- package/node_modules/projectstore/commands/research.md +17 -0
- package/node_modules/projectstore/commands/review.md +89 -0
- package/node_modules/projectstore/commands/runbook.md +17 -0
- package/node_modules/projectstore/commands/scaffold.md +23 -0
- package/node_modules/projectstore/commands/search.md +22 -0
- package/node_modules/projectstore/commands/spec.md +91 -0
- package/node_modules/projectstore/commands/status.md +27 -0
- package/node_modules/projectstore/commands/statusline.md +46 -0
- package/node_modules/projectstore/commands/story.md +113 -0
- package/node_modules/projectstore/docs/extending.md +172 -0
- package/node_modules/projectstore/docs/getting-started.md +133 -0
- package/node_modules/projectstore/docs/harnesses.md +176 -0
- package/node_modules/projectstore/docs/how-it-works.md +263 -0
- package/node_modules/projectstore/docs/images/loop-light.svg +94 -0
- package/node_modules/projectstore/docs/images/loop.svg +93 -0
- package/node_modules/projectstore/docs/images/statusline-hud.png +0 -0
- package/node_modules/projectstore/docs/images/team-light.svg +79 -0
- package/node_modules/projectstore/docs/images/team.svg +79 -0
- package/node_modules/projectstore/harnesses/claude-code.json +483 -0
- package/node_modules/projectstore/harnesses/codex.json +332 -0
- package/node_modules/projectstore/hooks/hooks.json +59 -0
- package/node_modules/projectstore/hooks/pre-compact.mjs +121 -0
- package/node_modules/projectstore/hooks/session-rules.mjs +63 -0
- package/node_modules/projectstore/hooks/session-start.mjs +301 -0
- package/node_modules/projectstore/hooks/session-stop.mjs +84 -0
- package/node_modules/projectstore/package.json +70 -0
- package/node_modules/projectstore/scaffold/checklists.json +88 -0
- package/node_modules/projectstore/scaffold/headings.json +171 -0
- package/node_modules/projectstore/scaffold/layouts/engineering.json +85 -0
- package/node_modules/projectstore/scripts/binding.mjs +165 -0
- package/node_modules/projectstore/scripts/build-adapters.mjs +264 -0
- package/node_modules/projectstore/scripts/cli.mjs +595 -0
- package/node_modules/projectstore/scripts/codemap.mjs +99 -0
- package/node_modules/projectstore/scripts/diff-refs.mjs +127 -0
- package/node_modules/projectstore/scripts/doctor.mjs +2127 -0
- package/node_modules/projectstore/scripts/draft.mjs +261 -0
- package/node_modules/projectstore/scripts/graph.mjs +219 -0
- package/node_modules/projectstore/scripts/harness.mjs +608 -0
- package/node_modules/projectstore/scripts/install-harness.mjs +1387 -0
- package/node_modules/projectstore/scripts/kanban.mjs +174 -0
- package/node_modules/projectstore/scripts/lib.mjs +3085 -0
- package/node_modules/projectstore/scripts/mcp.mjs +391 -0
- package/node_modules/projectstore/scripts/portable-registration.mjs +198 -0
- package/node_modules/projectstore/scripts/provenance.mjs +375 -0
- package/node_modules/projectstore/scripts/query.mjs +490 -0
- package/node_modules/projectstore/scripts/reconcile.mjs +422 -0
- package/node_modules/projectstore/scripts/statusline-launcher.mjs +141 -0
- package/node_modules/projectstore/scripts/statusline.mjs +253 -0
- package/node_modules/projectstore/scripts/story-section.mjs +209 -0
- package/node_modules/projectstore/scripts/surfaces.mjs +421 -0
- package/node_modules/projectstore/scripts/tokens.mjs +449 -0
- package/node_modules/projectstore/scripts/touch-session.mjs +336 -0
- package/node_modules/projectstore/scripts/version-guard.mjs +261 -0
- package/node_modules/projectstore/scripts/worktree.mjs +109 -0
- package/node_modules/projectstore/skills/projectstore-decision-detector/SKILL.md +40 -0
- package/node_modules/projectstore/skills/projectstore-peer-reviewer/SKILL.md +38 -0
- package/node_modules/projectstore/skills/projectstore-story-completion/SKILL.md +50 -0
- package/node_modules/projectstore/skills/projectstore-vault-communication/SKILL.md +96 -0
- package/node_modules/projectstore/templates/claude-md-block.md.tmpl +26 -0
- package/node_modules/projectstore/templates/de/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/de/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/de/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/de/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/de/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/de/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/de/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/de/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/de/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/de/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/de/strings.json +6 -0
- package/node_modules/projectstore/templates/en/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/en/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/en/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/en/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/en/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/en/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/en/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/en/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/en/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/en/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/en/strings.json +6 -0
- package/node_modules/projectstore/templates/es/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/es/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/es/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/es/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/es/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/es/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/es/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/es/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/es/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/es/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/es/strings.json +6 -0
- package/node_modules/projectstore/templates/fr/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/fr/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/fr/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/fr/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/fr/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/fr/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/fr/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/fr/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/fr/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/fr/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/fr/strings.json +6 -0
- package/node_modules/projectstore/templates/ru/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/ru/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/ru/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/ru/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/ru/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/ru/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/ru/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/ru/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/ru/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/ru/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/ru/strings.json +6 -0
- package/node_modules/projectstore/templates/zh/adr.md.tmpl +67 -0
- package/node_modules/projectstore/templates/zh/concept.md.tmpl +43 -0
- package/node_modules/projectstore/templates/zh/epic.md.tmpl +59 -0
- package/node_modules/projectstore/templates/zh/folder-readme.md.tmpl +14 -0
- package/node_modules/projectstore/templates/zh/kanban.md.tmpl +36 -0
- package/node_modules/projectstore/templates/zh/meeting.md.tmpl +38 -0
- package/node_modules/projectstore/templates/zh/research.md.tmpl +47 -0
- package/node_modules/projectstore/templates/zh/runbook.md.tmpl +53 -0
- package/node_modules/projectstore/templates/zh/spec.md.tmpl +64 -0
- package/node_modules/projectstore/templates/zh/story.md.tmpl +76 -0
- package/node_modules/projectstore/templates/zh/strings.json +6 -0
- package/package.json +35 -14
- package/skills/projectstore-adr/SKILL.md +76 -0
- package/skills/projectstore-agents/SKILL.md +50 -0
- package/skills/projectstore-archaeologist/SKILL.md +109 -0
- package/skills/projectstore-bind/SKILL.md +44 -0
- package/skills/projectstore-clerk/SKILL.md +126 -0
- package/skills/projectstore-codemap/SKILL.md +69 -0
- package/skills/projectstore-concept/SKILL.md +36 -0
- package/skills/projectstore-critic/SKILL.md +127 -0
- package/skills/projectstore-decision-detector/SKILL.md +59 -0
- package/skills/projectstore-doctor/SKILL.md +33 -0
- package/skills/projectstore-epic/SKILL.md +59 -0
- package/skills/projectstore-graph/SKILL.md +75 -0
- package/skills/projectstore-kanban/SKILL.md +60 -0
- package/skills/projectstore-librarian/SKILL.md +114 -0
- package/skills/projectstore-meeting/SKILL.md +36 -0
- package/skills/projectstore-peer-reviewer/SKILL.md +57 -0
- package/skills/projectstore-planner/SKILL.md +113 -0
- package/skills/projectstore-reconcile/SKILL.md +92 -0
- package/skills/projectstore-research/SKILL.md +36 -0
- package/skills/projectstore-review/SKILL.md +108 -0
- package/skills/projectstore-reviewer/SKILL.md +131 -0
- package/skills/projectstore-runbook/SKILL.md +36 -0
- package/skills/projectstore-scaffold/SKILL.md +42 -0
- package/skills/projectstore-search/SKILL.md +41 -0
- package/skills/projectstore-spec/SKILL.md +110 -0
- package/skills/projectstore-status/SKILL.md +47 -0
- package/skills/projectstore-statusline/SKILL.md +29 -0
- package/skills/projectstore-story/SKILL.md +132 -0
- package/skills/projectstore-story-completion/SKILL.md +69 -0
- package/skills/projectstore-vault-communication/SKILL.md +115 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// projectstore — worktree.mjs
|
|
3
|
+
// Answers one question: is this project an unbound git worktree of a checkout
|
|
4
|
+
// that IS bound, and therefore able to adopt its binding?
|
|
5
|
+
//
|
|
6
|
+
// `.gitignore` ignores `.claude/`, so a worktree created from a bound checkout
|
|
7
|
+
// starts with no projectstore.json: the hooks run, find nothing, and every
|
|
8
|
+
// /projectstore:* command is dead there. That is ADR decision 12 — the cheap,
|
|
9
|
+
// independent half of the parallel-session problem.
|
|
10
|
+
//
|
|
11
|
+
// Compute-only: spawns git, reads config files, writes nothing. The write path
|
|
12
|
+
// is /projectstore:bind --inherit, approval-gated like every other write.
|
|
13
|
+
|
|
14
|
+
import { dirname, resolve } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { projectRoot, readConfigAt, truncFront, PATH_CELL } from "./lib.mjs";
|
|
17
|
+
import { gitIn } from "./diff-refs.mjs";
|
|
18
|
+
|
|
19
|
+
// SessionStart is user-facing and budgets its gather in hundreds of
|
|
20
|
+
// milliseconds; diff-refs' 15 s batch default would be fifteen seconds of a
|
|
21
|
+
// hung session start.
|
|
22
|
+
const GIT_TIMEOUT_MS = 2000;
|
|
23
|
+
|
|
24
|
+
const git = (cwd, args) => gitIn(cwd, args, { timeout: GIT_TIMEOUT_MS });
|
|
25
|
+
|
|
26
|
+
const trim = (s) => (typeof s === "string" ? s.trim() : null);
|
|
27
|
+
|
|
28
|
+
// Every branch returns every field. A caller reading a field that only exists on
|
|
29
|
+
// the happy path throws, and a hook swallows that into silence — which looks
|
|
30
|
+
// exactly like the mechanism deciding it had nothing to say.
|
|
31
|
+
function record(state, worktree, mainCheckout, vaultPath) {
|
|
32
|
+
return { state, worktree, mainCheckout, vaultPath };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// The main checkout behind a linked worktree.
|
|
36
|
+
//
|
|
37
|
+
// `dirname(<git-common-dir>)` is right for an ordinary repository and WRONG for
|
|
38
|
+
// one created with --separate-git-dir, where the common dir sits outside any
|
|
39
|
+
// checkout — the vault on this machine has exactly that shape, and there both
|
|
40
|
+
// this and `git worktree list` name the git directory rather than a checkout.
|
|
41
|
+
//
|
|
42
|
+
// So the candidate is never trusted. Note what confirmation has to mean:
|
|
43
|
+
// `--show-toplevel` answering only proves the candidate sits inside *a* working
|
|
44
|
+
// tree, which is not the same as being the main checkout of *this* repository —
|
|
45
|
+
// and when a separate git dir happens to live inside an unrelated repository,
|
|
46
|
+
// that weaker check names the stranger and we would offer its vault. Identity is
|
|
47
|
+
// therefore confirmed by asking the candidate for its own common dir and
|
|
48
|
+
// requiring it to be the one we started from. Not knowing yields null, and null
|
|
49
|
+
// must never produce an offer.
|
|
50
|
+
function mainCheckoutOf(commonDir) {
|
|
51
|
+
const candidate = dirname(commonDir);
|
|
52
|
+
const top = trim(git(candidate, ["rev-parse", "--path-format=absolute", "--show-toplevel"]));
|
|
53
|
+
if (!top) return null;
|
|
54
|
+
const topCommon = trim(git(top, ["rev-parse", "--path-format=absolute", "--git-common-dir"]));
|
|
55
|
+
return topCommon === commonDir ? top : null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function resolveBinding(projectDir = projectRoot()) {
|
|
59
|
+
// A bound project has nothing to ask, so it never pays for a git spawn. The
|
|
60
|
+
// `worktree` field therefore means "detected as a linked worktree", and
|
|
61
|
+
// detection only runs when unbound — `false` here is "not asked", not "no".
|
|
62
|
+
if (readConfigAt(projectDir)) return record("bound", false, null, null);
|
|
63
|
+
|
|
64
|
+
const gitDir = trim(git(projectDir, ["rev-parse", "--path-format=absolute", "--git-dir"]));
|
|
65
|
+
const commonDir = trim(git(projectDir, ["rev-parse", "--path-format=absolute", "--git-common-dir"]));
|
|
66
|
+
// Git missing (ENOENT → status null) and a non-repository (exit 128) both land
|
|
67
|
+
// here, and both are ordinary unbound projects with the ordinary advice.
|
|
68
|
+
if (!gitDir || !commonDir) return record("unbound", false, null, null);
|
|
69
|
+
|
|
70
|
+
// --path-format=absolute matters: in a main checkout the common dir comes back
|
|
71
|
+
// as the relative `.git`, and dirname() of that is `.`.
|
|
72
|
+
if (gitDir === commonDir) return record("unbound", false, null, null);
|
|
73
|
+
|
|
74
|
+
const main = mainCheckoutOf(commonDir);
|
|
75
|
+
if (!main) return record("unbound", true, null, null);
|
|
76
|
+
|
|
77
|
+
const parent = readConfigAt(main);
|
|
78
|
+
if (!parent || !parent.vault_path) return record("unbound", true, main, null);
|
|
79
|
+
|
|
80
|
+
return record("inheritable", true, main, parent.vault_path);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Pure: record in, block out. Both interpolated paths are user-controlled and
|
|
84
|
+
// unbounded, so both go through the same cell truncation the sibling warning
|
|
85
|
+
// uses — the composed SessionStart value is capped and this is one of its terms.
|
|
86
|
+
export function bindingOfferText(b) {
|
|
87
|
+
return [
|
|
88
|
+
"# projectstore — this worktree is not bound",
|
|
89
|
+
"",
|
|
90
|
+
"This checkout has no `.projectstore/projectstore.json`, so `/projectstore:*` commands",
|
|
91
|
+
"cannot run here. The checkout it was forked from is bound:",
|
|
92
|
+
"",
|
|
93
|
+
`- main checkout: \`${truncFront(String(b.mainCheckout), PATH_CELL)}\``,
|
|
94
|
+
`- its vault: \`${truncFront(String(b.vaultPath), PATH_CELL)}\``,
|
|
95
|
+
"",
|
|
96
|
+
"Run `/projectstore:bind --inherit` to adopt that binding. It copies the binding",
|
|
97
|
+
"only — the vault is shared and unchanged, and no session state travels with it.",
|
|
98
|
+
"",
|
|
99
|
+
"",
|
|
100
|
+
].join("\n");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function main() {
|
|
104
|
+
process.stdout.write(JSON.stringify(resolveBinding(projectRoot()), null, 2) + "\n");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
108
|
+
main();
|
|
109
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: projectstore-decision-detector
|
|
3
|
+
description: When the user makes or accepts an architectural/technical decision (choosing between alternatives, locking in a pattern, picking a library or tool, settling a trade-off), suggest capturing it as an ADR via /projectstore:adr. Never write to the vault directly — only suggest, and let the /projectstore:adr command handle approval.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Decision detector
|
|
7
|
+
|
|
8
|
+
You watch for **decision moments** in the conversation:
|
|
9
|
+
|
|
10
|
+
- The user explicitly chose between two or more alternatives ("we'll go with X over Y").
|
|
11
|
+
- A trade-off was settled ("let's accept the latency hit for stronger consistency").
|
|
12
|
+
- A library, framework, pattern, or tool was committed to.
|
|
13
|
+
- An architectural property was fixed (auth model, storage layout, transport protocol, deployment topology).
|
|
14
|
+
|
|
15
|
+
## When you detect such a moment
|
|
16
|
+
|
|
17
|
+
1. **Check if a vault is bound**: confirm `.projectstore/projectstore.json` exists in the current project. If not, do nothing — this skill is silent without binding.
|
|
18
|
+
|
|
19
|
+
2. **Check `active_skills` in the config**. If `false`, do nothing.
|
|
20
|
+
|
|
21
|
+
3. **Check for an existing ADR** on the same topic first:
|
|
22
|
+
```bash
|
|
23
|
+
grep -rli "<key-term>" "<vault>/adr/" 2>/dev/null
|
|
24
|
+
```
|
|
25
|
+
If a matching ADR exists, suggest **updating** it (Read + propose Edit through normal approval flow) rather than creating a duplicate.
|
|
26
|
+
|
|
27
|
+
4. **Suggest, do not act**. Write one short message to the user:
|
|
28
|
+
|
|
29
|
+
> 💡 *This looks like a decision worth recording. Want me to draft an ADR? Run `/projectstore:adr "<your-title>"` or just say "yes" and I'll fire it with the title above.*
|
|
30
|
+
|
|
31
|
+
Propose a concise title (≤80 chars), e.g. *"Use BFF pattern for OIDC"*.
|
|
32
|
+
|
|
33
|
+
5. **Wait for explicit user confirmation** before invoking `/projectstore:adr`. Never auto-execute.
|
|
34
|
+
|
|
35
|
+
## Anti-patterns (do not do)
|
|
36
|
+
|
|
37
|
+
- Don't suggest an ADR for trivial choices (variable names, formatting).
|
|
38
|
+
- Don't suggest an ADR more than once per detected decision — if the user said "not now", drop it for the session.
|
|
39
|
+
- Don't write any vault file directly from this skill. ADR creation always goes through `/projectstore:adr` which gates writes with `AskUserQuestion`.
|
|
40
|
+
- Don't change the ADR template, status, or numbering — that's `/projectstore:adr`'s job.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: projectstore-peer-reviewer
|
|
3
|
+
description: After a new projectstore artifact is created via /projectstore:adr, /projectstore:research, or /projectstore:epic (and similar generative commands), suggest running /projectstore:review <path> to peer-review the artifact with a fresh critic agent before it's committed. Only suggest for artifact kinds whose checklist has default_review=true. Never auto-execute — always ask first.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Peer-reviewer skill
|
|
7
|
+
|
|
8
|
+
You watch for moments where a new artifact has just been written by a `/projectstore:*` command and could benefit from peer review **before** it lands in git.
|
|
9
|
+
|
|
10
|
+
## Trigger conditions
|
|
11
|
+
|
|
12
|
+
After a successful invocation of any of:
|
|
13
|
+
|
|
14
|
+
- `/projectstore:adr` — new ADR created
|
|
15
|
+
- `/projectstore:research` — new research note created
|
|
16
|
+
- `/projectstore:epic` — new epic created
|
|
17
|
+
|
|
18
|
+
(See `scaffold/checklists.json` — kinds with `default_review: true`.)
|
|
19
|
+
|
|
20
|
+
## What to do
|
|
21
|
+
|
|
22
|
+
1. **Confirm a vault is bound** (`.projectstore/projectstore.json` exists). Otherwise stay silent.
|
|
23
|
+
2. **Confirm `active_skills: true`** in config.
|
|
24
|
+
3. **Read the frontmatter** of the freshly created file. If `review_status: pending` — eligible for suggestion. If `review_status: reviewed` or `n/a` — do nothing.
|
|
25
|
+
4. **Suggest, do not act**. One short message:
|
|
26
|
+
|
|
27
|
+
> 🔍 *Want me to peer-review this <kind> before committing? `/projectstore:review <path>` spawns a fresh critic that hasn't seen our conversation — different angle, often catches missing alternatives or unstated assumptions.*
|
|
28
|
+
|
|
29
|
+
5. **Wait for explicit user confirmation** before invoking `/projectstore:review`. Never auto-execute.
|
|
30
|
+
|
|
31
|
+
6. If the user declines, drop it for this session — don't ask again for the same file.
|
|
32
|
+
|
|
33
|
+
## Anti-patterns
|
|
34
|
+
|
|
35
|
+
- Don't suggest review for kinds with `default_review: false` (meeting, runbook, story, concept). User can still invoke `/projectstore:review` manually if they want.
|
|
36
|
+
- Don't suggest review more than once per artifact per session.
|
|
37
|
+
- Don't run the review yourself — `/projectstore:review` handles the critic spawn, the approval flow, and the frontmatter update.
|
|
38
|
+
- Don't reframe the suggestion as "this might need improvement" — that's sycophancy in disguise. The framing is "fresh-eyes pass", not "your work has problems".
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: projectstore-story-completion
|
|
3
|
+
description: When the user finishes work that maps to a known story (story file exists in epics/<id>/stories/) — all acceptance criteria appear satisfied, code merged, tests passing — suggest updating the story's frontmatter status (e.g. planned → in-progress → review → done) and regenerating the kanban. Never write to vault directly without /projectstore:* commands and explicit approval.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Story completion / status update suggester
|
|
7
|
+
|
|
8
|
+
You watch for moments where the conversation indicates progress on a known story:
|
|
9
|
+
|
|
10
|
+
- A merge/PR was completed for work tied to a story.
|
|
11
|
+
- The user said "story-001 is done" or similar.
|
|
12
|
+
- All checkboxes in a story's `Decomposition` or `Acceptance Criteria` got ticked.
|
|
13
|
+
- The user moved between phases of an epic (e.g., "moving to integration testing now").
|
|
14
|
+
|
|
15
|
+
## What to do
|
|
16
|
+
|
|
17
|
+
1. **Confirm a vault is bound** (`.projectstore/projectstore.json` exists). Otherwise stay silent.
|
|
18
|
+
2. **Confirm `active_skills` is true** in config.
|
|
19
|
+
3. **Try to identify the story file**: search `<vault>/epics/*/stories/` for files matching keywords from the conversation. If multiple candidates, ask the user which one via plain text (not AskUserQuestion — keep it light).
|
|
20
|
+
4. **Propose the right transition**:
|
|
21
|
+
- Work about to **start** on a story → suggest `/projectstore:story plan <story>`
|
|
22
|
+
(writes the Implementation Plan, stamps `started_at`, moves to in-progress).
|
|
23
|
+
- Story looks **finished** → suggest `/projectstore:story close <story>`
|
|
24
|
+
(Final Summary, evidence suffixes on acceptance criteria, stamps
|
|
25
|
+
`closed_at`, moves to done) — and, before closing, the `reviewer` agent,
|
|
26
|
+
whose proposed `code_refs` come from `scripts/diff-refs.mjs` anchored at
|
|
27
|
+
the story's `started_at`.
|
|
28
|
+
- Intermediate move (e.g. → review) → propose the frontmatter status Edit
|
|
29
|
+
as before:
|
|
30
|
+
|
|
31
|
+
> 📋 *Looks like `epics/RECPLAT-333/stories/story-007-feature-pipeline.md` is moving to `review`. Want me to update its frontmatter and refresh the kanban?*
|
|
32
|
+
|
|
33
|
+
5. **Do not modify the file** until the user says yes. When they confirm a
|
|
34
|
+
plain status move:
|
|
35
|
+
- Read the story file.
|
|
36
|
+
- Propose an Edit that changes `status:` and `updated:` in the frontmatter
|
|
37
|
+
(plus `started_at` when first entering in-progress outside the plan gate,
|
|
38
|
+
`closed_at` when moving to done outside the close gate — timestamps must
|
|
39
|
+
not be lost just because the gate was skipped; ISO-8601).
|
|
40
|
+
- Use AskUserQuestion to confirm the Edit before applying.
|
|
41
|
+
- After Edit, suggest running `/projectstore:kanban` to refresh the board.
|
|
42
|
+
|
|
43
|
+
## Anti-patterns
|
|
44
|
+
|
|
45
|
+
- Don't pick a story automatically — always ask if uncertain.
|
|
46
|
+
- Don't bulk-update multiple stories in one go without per-file approval.
|
|
47
|
+
- Don't change anything beyond `status`, `updated` and the lifecycle
|
|
48
|
+
timestamps (`started_at` / `closed_at`). Section content (plan, summary,
|
|
49
|
+
evidence) belongs to the `/projectstore:story plan|close` gates.
|
|
50
|
+
- Don't trigger after every code change — only on clear completion signals.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: projectstore-vault-communication
|
|
3
|
+
description: When communicating with the user about anything stored in the projectstore vault (epics, stories, ADRs, research, kanban, backlog), reference every artifact by its human title from frontmatter — never by session-invented shorthand. Name the parent epic for stories; include status/priority when discussing state or plans. Applies by default in bound projects to summaries, plans, and progress reports.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vault-native communication
|
|
7
|
+
|
|
8
|
+
Vault artifacts are the shared vocabulary between the user, this session, *other*
|
|
9
|
+
sessions, and the post-compact agent. A title written in a file can be grepped,
|
|
10
|
+
linked, and recognized in Obsidian six months from now. A label invented mid-session
|
|
11
|
+
("T3", "P0-1", "the doctor story") dies with the session that coined it — and forces
|
|
12
|
+
the user to cross-reference your earlier messages just to know what you meant.
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
|
|
16
|
+
### 1. Call artifacts by their `title:`, not by number or slug
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
bad: story-004 is done, story-005 is next
|
|
20
|
+
good: "Unicode-aware slugify to unbreak ru filenames" (story-004) is done;
|
|
21
|
+
"YAML-escape template variables" (story-005) is next
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The id in parentheses is welcome — as a *supplement*, never the only handle.
|
|
25
|
+
|
|
26
|
+
### 2. Stories always carry their epic
|
|
27
|
+
|
|
28
|
+
First mention in a message names both; after that a short form is fine.
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
bad: let's start with story-001
|
|
32
|
+
good: let's start with "doctor: deterministic consistency lint" (PS-IMPROVE › story-001)
|
|
33
|
+
then: doctor lint story (story-001)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 3. Resolution order for the name
|
|
37
|
+
|
|
38
|
+
`title:` from frontmatter → filename without extension → relative path.
|
|
39
|
+
Never a bare number ("story 3", "the second ADR").
|
|
40
|
+
|
|
41
|
+
### 4. Plans and progress carry status (and priority when it matters)
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
bad: the epic is moving along
|
|
45
|
+
good: epic "Reliability by construction" (PS-IMPROVE, p0): 2 of 6 stories done,
|
|
46
|
+
"reconcile: re-derive kanban and indexes from frontmatter" is in-progress
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 5. Document-internal codes stay inside their document
|
|
50
|
+
|
|
51
|
+
If a note defines its own legend (e.g. topics T1–T6 in a research note), those codes
|
|
52
|
+
are fine *within that document*. In chat, expand them on first use in every message:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
bad: I suggest T3+T4 first, then T2/T6, T5, T1
|
|
56
|
+
good: I suggest starting with the agent-roster topics — "which new roles fit" and
|
|
57
|
+
"rename projectstore-critic → critic" (topics 3–4 in research "v0.13 Design
|
|
58
|
+
Questions: Statusline, Agents, Doctor, Model Config") — their naming decisions
|
|
59
|
+
leak into every other ADR's wording
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 6. Link the file when the user may want to open it
|
|
63
|
+
|
|
64
|
+
`epics/PS-IMPROVE/stories/story-001-doctor-deterministic-consistency-lint.md` —
|
|
65
|
+
paths are clickable in the terminal and resolvable in Obsidian. Title first,
|
|
66
|
+
path as the pointer.
|
|
67
|
+
|
|
68
|
+
## When this applies
|
|
69
|
+
|
|
70
|
+
- Any user-facing message *about vault contents*: status summaries, "what's next",
|
|
71
|
+
planning discussions, review results, kanban talk, backlog updates.
|
|
72
|
+
- Artifacts you write into the vault: related-links and prose references use titles
|
|
73
|
+
and wiki-links, not invented codes.
|
|
74
|
+
|
|
75
|
+
## When it does NOT apply
|
|
76
|
+
|
|
77
|
+
- Short confirmations ("done", "committing now") with no artifact references.
|
|
78
|
+
- Raw command output, code blocks, file paths inside tool calls.
|
|
79
|
+
- Frontmatter ids themselves (`id: story-001` stays an id — that's its job).
|
|
80
|
+
|
|
81
|
+
## Anti-patterns
|
|
82
|
+
|
|
83
|
+
- ❌ "T3+T4 first, then T2/T6" — bare document-internal codes leaked into chat.
|
|
84
|
+
- ❌ "P0-1 through P0-6 are specced" — priority labels used as names.
|
|
85
|
+
- ❌ "the doctor story" when two doctor-shaped items exist (install diagnostics vs
|
|
86
|
+
vault consistency lint) — ambiguity is exactly what titles prevent.
|
|
87
|
+
- ❌ Renaming an artifact in conversation ("the reliability epic" for an epic titled
|
|
88
|
+
"Reliability by construction" is fine as a gloss — but don't *invent* a different
|
|
89
|
+
working title and keep using it).
|
|
90
|
+
|
|
91
|
+
## Activation
|
|
92
|
+
|
|
93
|
+
Default-on when a vault is bound (`.projectstore/projectstore.json` exists) and
|
|
94
|
+
`active_skills` is not `false` — same gating as the other passive skills. Silent
|
|
95
|
+
otherwise. This skill changes *how you phrase things*; it never writes files and
|
|
96
|
+
never blocks an action.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!-- projectstore:agents v4 (managed by projectstore — edit outside markers) -->
|
|
2
|
+
## projectstore agents
|
|
3
|
+
|
|
4
|
+
- **A feature-sized request opens a vault artifact before it opens an editor.**
|
|
5
|
+
Analysis → placement (which epic, which story) → an ADR and/or spec when the
|
|
6
|
+
"how" is non-trivial → `projectstore:critic` → only then implementation →
|
|
7
|
+
`projectstore:reviewer`. "Feature-sized" is not a judgement about how the
|
|
8
|
+
request was phrased — it is about what the work touches: if you are about to
|
|
9
|
+
write across several source files, open the story first.
|
|
10
|
+
- **Report instruction conflicts; do not arbitrate them.** If a session-level or
|
|
11
|
+
harness-level instruction contradicts this block, say so and ask which wins.
|
|
12
|
+
Resolving it silently is how the contradiction becomes invisible to the person
|
|
13
|
+
who could have settled it.
|
|
14
|
+
- When spawning any agent below, resolve its model from
|
|
15
|
+
`.projectstore/harness/<harness>.json` → `agents.per_agent.<name>.model ?? agents.default.model`,
|
|
16
|
+
where `<name>` is the **bare** agent name (`critic` for `projectstore:critic`),
|
|
17
|
+
and pass it as the spawn's model parameter. No key — pass nothing.
|
|
18
|
+
- After authoring or revising any vault artifact (ADR/research/epic/story) or
|
|
19
|
+
design proposal: run the `projectstore:critic` agent on it before treating it final.
|
|
20
|
+
- Before implementing an epic/story: consult `projectstore:planner` — it plans
|
|
21
|
+
against how prior epics map to the codebase (`code_refs`).
|
|
22
|
+
- After writing code, before commit / story-done: run `projectstore:reviewer` —
|
|
23
|
+
it verifies the diff actually closes the story's acceptance criteria.
|
|
24
|
+
- When discussing vault contents, reference artifacts by their frontmatter
|
|
25
|
+
`title:` (with their parent epic), never by session-invented shorthand.
|
|
26
|
+
<!-- /projectstore:agents -->
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: adr
|
|
3
|
+
id: {{id_json}}
|
|
4
|
+
title: {{title_json}}
|
|
5
|
+
status: proposed
|
|
6
|
+
date: {{date}}
|
|
7
|
+
authors: [{{author_json}}]
|
|
8
|
+
tags: {{tags}}
|
|
9
|
+
external_refs: {}
|
|
10
|
+
supersedes: null
|
|
11
|
+
superseded_by: null
|
|
12
|
+
review_status: pending
|
|
13
|
+
reviewed_at: null
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# {{title}}
|
|
17
|
+
|
|
18
|
+
| Feld | Wert |
|
|
19
|
+
|---|---|
|
|
20
|
+
| **Status** | proposed |
|
|
21
|
+
| **Datum** | {{date}} |
|
|
22
|
+
| **Autoren** | {{author}} |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Kontext
|
|
27
|
+
|
|
28
|
+
<!-- Welche Kräfte wirken? Warum ist die Entscheidung jetzt nötig? -->
|
|
29
|
+
|
|
30
|
+
## Entscheidung
|
|
31
|
+
|
|
32
|
+
<!-- Die Entscheidung selbst, klar und knapp formuliert. -->
|
|
33
|
+
|
|
34
|
+
## Begründung
|
|
35
|
+
|
|
36
|
+
<!-- Warum diese Entscheidung und nicht die Alternativen. Nummerierte Gründe bevorzugt. -->
|
|
37
|
+
|
|
38
|
+
## Betrachtete Alternativen
|
|
39
|
+
|
|
40
|
+
### Alternative A: {{alternative_a_name}}
|
|
41
|
+
|
|
42
|
+
**Vorteile**:
|
|
43
|
+
-
|
|
44
|
+
|
|
45
|
+
**Nachteile**:
|
|
46
|
+
-
|
|
47
|
+
|
|
48
|
+
**Abgelehnt, weil**:
|
|
49
|
+
|
|
50
|
+
## Konsequenzen
|
|
51
|
+
|
|
52
|
+
**Positiv**:
|
|
53
|
+
-
|
|
54
|
+
|
|
55
|
+
**Negativ / Kompromisse**:
|
|
56
|
+
-
|
|
57
|
+
|
|
58
|
+
**Was sich in Code / Prozess ändert**:
|
|
59
|
+
-
|
|
60
|
+
|
|
61
|
+
## Referenzen
|
|
62
|
+
|
|
63
|
+
-
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
*Zuletzt aktualisiert: {{date}}*
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: concept
|
|
3
|
+
slug: {{slug_json}}
|
|
4
|
+
title: {{title_json}}
|
|
5
|
+
status: draft
|
|
6
|
+
date: {{date}}
|
|
7
|
+
authors: [{{author_json}}]
|
|
8
|
+
tags: {{tags}}
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# {{title}}
|
|
12
|
+
|
|
13
|
+
## Was ist das
|
|
14
|
+
|
|
15
|
+
<!-- Definition in einem Absatz. -->
|
|
16
|
+
|
|
17
|
+
## Warum es zählt
|
|
18
|
+
|
|
19
|
+
<!-- Kontext, welches Problem dieses Konzept adressiert. -->
|
|
20
|
+
|
|
21
|
+
## Wie es funktioniert
|
|
22
|
+
|
|
23
|
+
<!-- Mechanismus, Komponenten, Zusammenspiel. -->
|
|
24
|
+
|
|
25
|
+
## Wann einsetzen / nicht einsetzen
|
|
26
|
+
|
|
27
|
+
**Einsetzen, wenn**:
|
|
28
|
+
-
|
|
29
|
+
|
|
30
|
+
**Nicht einsetzen, wenn**:
|
|
31
|
+
-
|
|
32
|
+
|
|
33
|
+
## Verwandtes
|
|
34
|
+
|
|
35
|
+
-
|
|
36
|
+
|
|
37
|
+
## Referenzen
|
|
38
|
+
|
|
39
|
+
-
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
*Zuletzt aktualisiert: {{date}}*
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: epic
|
|
3
|
+
id: {{id_json}}
|
|
4
|
+
title: {{title_json}}
|
|
5
|
+
status: planned
|
|
6
|
+
priority: p2
|
|
7
|
+
created: {{date}}
|
|
8
|
+
updated: {{date}}
|
|
9
|
+
external_refs: {}
|
|
10
|
+
tags: {{tags}}
|
|
11
|
+
code_refs: []
|
|
12
|
+
review_status: pending
|
|
13
|
+
reviewed_at: null
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# {{id}}: {{title}}
|
|
17
|
+
|
|
18
|
+
| Feld | Wert |
|
|
19
|
+
|---|---|
|
|
20
|
+
| **Status** | planned |
|
|
21
|
+
| **Priorität** | p2 |
|
|
22
|
+
| **Erstellt** | {{date}} |
|
|
23
|
+
| **Aktualisiert** | {{date}} |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Ziel
|
|
28
|
+
|
|
29
|
+
<!-- Wie sieht Erfolg für dieses Epic aus? -->
|
|
30
|
+
|
|
31
|
+
## Kontext
|
|
32
|
+
|
|
33
|
+
<!-- Hintergrund, Motivation, warum das jetzt wichtig ist. -->
|
|
34
|
+
|
|
35
|
+
## Stories
|
|
36
|
+
|
|
37
|
+
| Story | Status | Beschreibung |
|
|
38
|
+
|-------|--------|--------------|
|
|
39
|
+
| [story-001](./stories/story-001.md) | planned | |
|
|
40
|
+
|
|
41
|
+
## Erwartete Ergebnisse
|
|
42
|
+
|
|
43
|
+
- [ ]
|
|
44
|
+
|
|
45
|
+
## Abhängigkeiten
|
|
46
|
+
|
|
47
|
+
-
|
|
48
|
+
|
|
49
|
+
## Offene Fragen
|
|
50
|
+
|
|
51
|
+
- [ ]
|
|
52
|
+
|
|
53
|
+
## Verwandtes
|
|
54
|
+
|
|
55
|
+
-
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
*Zuletzt aktualisiert: {{date}}*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# {{folder_name}}
|
|
2
|
+
|
|
3
|
+
{{folder_description}}
|
|
4
|
+
|
|
5
|
+
## Index
|
|
6
|
+
|
|
7
|
+
<!-- projectstore hält diesen Index aktuell, wenn Einträge über die /projectstore:*-Kommandos hinzukommen. -->
|
|
8
|
+
|
|
9
|
+
| Datei | Titel | Status | Datum |
|
|
10
|
+
|-------|-------|--------|-------|
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
*Verwaltet vom projectstore-Plugin. Manuelle Änderungen außerhalb der Index-Tabelle bleiben erhalten.*
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
kanban-plugin: board
|
|
4
|
+
projectstore: derived
|
|
5
|
+
generated_at: {{generated_at}}
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Backlog
|
|
10
|
+
|
|
11
|
+
{{backlog_items}}
|
|
12
|
+
|
|
13
|
+
## Zu erledigen
|
|
14
|
+
|
|
15
|
+
{{todo_items}}
|
|
16
|
+
|
|
17
|
+
## In Arbeit
|
|
18
|
+
|
|
19
|
+
{{in_progress_items}}
|
|
20
|
+
|
|
21
|
+
## Review
|
|
22
|
+
|
|
23
|
+
{{review_items}}
|
|
24
|
+
|
|
25
|
+
## Fertig
|
|
26
|
+
|
|
27
|
+
{{done_items}}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
%% kanban:settings
|
|
33
|
+
```
|
|
34
|
+
{"kanban-plugin":"board","list-collapse":[false,false,false,false,false]}
|
|
35
|
+
```
|
|
36
|
+
%%
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: meeting
|
|
3
|
+
date: {{date}}
|
|
4
|
+
slug: {{slug_json}}
|
|
5
|
+
title: {{title_json}}
|
|
6
|
+
attendees: []
|
|
7
|
+
tags: {{tags}}
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# {{date}} — {{title}}
|
|
11
|
+
|
|
12
|
+
## Teilnehmende
|
|
13
|
+
|
|
14
|
+
-
|
|
15
|
+
|
|
16
|
+
## Agenda
|
|
17
|
+
|
|
18
|
+
-
|
|
19
|
+
|
|
20
|
+
## Notizen
|
|
21
|
+
|
|
22
|
+
###
|
|
23
|
+
|
|
24
|
+
## Entscheidungen
|
|
25
|
+
|
|
26
|
+
- [ ]
|
|
27
|
+
|
|
28
|
+
## Aufgaben
|
|
29
|
+
|
|
30
|
+
- [ ] **{{author}}**:
|
|
31
|
+
|
|
32
|
+
## Nachfassen
|
|
33
|
+
|
|
34
|
+
-
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
*Notiert von: {{author}}*
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: research
|
|
3
|
+
slug: {{slug_json}}
|
|
4
|
+
title: {{title_json}}
|
|
5
|
+
status: draft
|
|
6
|
+
date: {{date}}
|
|
7
|
+
authors: [{{author_json}}]
|
|
8
|
+
tags: {{tags}}
|
|
9
|
+
review_status: pending
|
|
10
|
+
reviewed_at: null
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# {{title}}
|
|
14
|
+
|
|
15
|
+
## Fragestellung
|
|
16
|
+
|
|
17
|
+
<!-- Was wollen wir herausfinden? -->
|
|
18
|
+
|
|
19
|
+
## Kurzfassung (TL;DR)
|
|
20
|
+
|
|
21
|
+
<!-- Antwort in einem Absatz. Nach dem Hauptteil ausfüllen. -->
|
|
22
|
+
|
|
23
|
+
## Vorgehen
|
|
24
|
+
|
|
25
|
+
<!-- Wie wir untersucht haben: Quellen, Experimente, Benchmarks. -->
|
|
26
|
+
|
|
27
|
+
## Ergebnisse
|
|
28
|
+
|
|
29
|
+
###
|
|
30
|
+
|
|
31
|
+
## Vergleich
|
|
32
|
+
|
|
33
|
+
| Option | Vorteile | Nachteile |
|
|
34
|
+
|--------|----------|-----------|
|
|
35
|
+
| | | |
|
|
36
|
+
|
|
37
|
+
## Fazit
|
|
38
|
+
|
|
39
|
+
<!-- Was wir empfehlen und warum. -->
|
|
40
|
+
|
|
41
|
+
## Referenzen
|
|
42
|
+
|
|
43
|
+
-
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
*Zuletzt aktualisiert: {{date}}*
|