oris-skills 3.0.1 → 3.0.3

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oris-skills",
3
3
  "description": "Oris Skills: one entry point (/oris-flow) and a guided discovery-to-implementation flow. Cross-model: Cursor, Claude Code, Codex.",
4
- "version": "3.0.1",
4
+ "version": "3.0.3",
5
5
  "author": {
6
6
  "name": "Davide Baldassarre"
7
7
  },
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.3 - 2026-07-14
4
+
5
+ - **Native route questions restored.** Ambiguous `/oris-flow` requests now traverse a
6
+ bounded, outcome-based navigator through Cursor `AskQuestion` or Claude
7
+ `AskUserQuestion`; text fallback is used only when no question tool is available.
8
+ - **Question capability is detected, not inferred from mode.** Cursor Agent Mode can use
9
+ its native question UI when the runtime exposes it.
10
+ - **Release drift is blocked.** Package and Cursor plugin versions must match, and real
11
+ temporary Cursor and Claude installs verify self-contained references and version
12
+ markers.
13
+
3
14
  ## 3.0.1 - 2026-07-10
4
15
 
5
16
  The lean core: one skill, one durable store, evidence on both sides of the repo boundary.
package/README.md CHANGED
@@ -30,7 +30,9 @@ fixes the colleague part with three rules baked into every interaction:
30
30
 
31
31
  `/oris-flow` reads your intent and enters the right route in the same chat — no other
32
32
  command exists. Say "the login button does nothing" and you are in **fix**; say "the
33
- client changed their mind about invoicing" and you are in **change**.
33
+ client changed their mind about invoicing" and you are in **change**; say "a client
34
+ reported this, park it" and **triage** captures it as a work item; say "I'm out of
35
+ context" and **handoff** packages the session for the next one.
34
36
 
35
37
  ```text
36
38
  idea ──► discover ──► criteria ──► plan ──► implement ──► verify
@@ -42,6 +44,7 @@ client changed their mind about invoicing" and you are in **change**.
42
44
  |-------|---------|
43
45
  | **setup** | the repo made agent-ready: detected commands and structure confirmed into `AGENTS.md`; AI-readiness check |
44
46
  | **new** | a greenfield project born agent-native: sparse `AGENTS.md`, domain glossary, first ADR, red→green test observed |
47
+ | **triage** | raw intake — an idea, a bug report — becomes a work item with an agent-ready brief, duplicates linked, routed onward |
45
48
  | **discover** | business-first interview → `functional-analysis.md` |
46
49
  | **criteria** | observable, stable-ID acceptance criteria → `acceptance-criteria.md` |
47
50
  | **plan** | technical interview → `implementation-plan.md` with bounded, verifiable steps — external APIs verified against their docs, sources recorded |
@@ -50,6 +53,7 @@ client changed their mind about invoicing" and you are in **change**.
50
53
  | **change** | spec delta interviewed, **all** documents updated in one approved pass → `change-log.md` |
51
54
  | **architecture / docs / help** | deepening review, doc alignment, answers |
52
55
  | **commit / pr** | Conventional Commits and English PRs, work item linked, always gated |
56
+ | **handoff** | session state packaged outside the repo — decisions, evidence, next move — so a fresh session resumes exactly there |
53
57
 
54
58
  Every route follows one skeleton — what to do, what **Never** to do, and a **Done when**
55
59
  checklist — enforced by the test suite, so the discipline survives refactors.
@@ -6,9 +6,9 @@ Install once, remember one command:
6
6
  npx oris-skills@latest install # detects Cursor / Claude Code / Codex / Copilot (VS Code)
7
7
  ```
8
8
 
9
- Then type **`/oris-flow`** in your agent chat. It routes your request or shows a short menu (setup, new project, discovery, criteria, plan, implement/fix, verify, spec change, architecture review, docs, commit, pull request, help). The skill never triggers itself — you invoke it. On Codex use the installed `/oris-flow` prompt; on Copilot Chat use `/oris-flow` too (enable the VS Code setting `chat.promptFiles` once). Any other agent: tell it to read `~/.oris/oris-flow.md`.
9
+ Then type **`/oris-flow`** in your agent chat. It routes your request or shows a short menu (setup, new project, triage, discovery, criteria, plan, implement/fix, verify, spec change, architecture review, docs, commit, pull request, handoff, help). The skill never triggers itself — you invoke it. On Codex use the installed `/oris-flow` prompt; on Copilot Chat use `/oris-flow` too (enable the VS Code setting `chat.promptFiles` once). Any other agent: tell it to read `~/.oris/oris-flow.md`.
10
10
 
11
- The flow in one line: **discover → criteria → plan → implement → verify**, with `fix` for bugs and `change` when the spec changes mid-flight (it updates all task docs together and logs `CH-xxx` history). `new` bootstraps an AI-driven project from scratch; `architecture` maps deepening/refactor opportunities. Task documents live in `.oris-flow/tasks/` by default — your project's own docs stay untouched.
11
+ The flow in one line: **discover → criteria → plan → implement → verify**, with `fix` for bugs and `change` when the spec changes mid-flight (it updates all task docs together and logs `CH-xxx` history). `new` bootstraps an AI-driven project from scratch; `architecture` maps deepening/refactor opportunities. `triage` turns raw ideas and bug reports into work items on your DevOps board before the flow starts; `handoff` packages a session's state — decisions, evidence, next move — so a fresh session resumes exactly where this one stopped. Task documents live in `.oris-flow/tasks/` by default — your project's own docs stay untouched.
12
12
 
13
13
  ## What setup leaves in your repo
14
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oris-skills",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Oris Skills: one entry point (/oris-flow) and a guided discovery-to-implementation flow for Cursor, Claude Code, and Codex.",
5
5
  "license": "MIT",
6
6
  "author": "Davide Baldassarre",
@@ -1,6 +1,6 @@
1
1
  # Clean Code Checklist
2
2
 
3
- Used by `oris-flow-implement` and `oris-flow-fix` while closing work: clean what YOU introduced, in the files you touched. Investigate before concluding; absence in one file is not proof of dead code.
3
+ Used by `skills/oris-flow/references/implement.md` and `skills/oris-flow/references/fix.md` while closing work: clean what YOU introduced, in the files you touched. Investigate before concluding; absence in one file is not proof of dead code.
4
4
 
5
5
  ## Check, in the touched scope only
6
6
 
@@ -15,6 +15,6 @@ Used by `oris-flow-implement` and `oris-flow-fix` while closing work: clean what
15
15
 
16
16
  Before removing anything: search references and call sites (including DI registration, reflection, dynamic imports, routing, code generation, framework conventions). Tests, config, or registration may still require the symbol.
17
17
 
18
- ## Never here
18
+ ## Never
19
19
 
20
20
  Bug fixes (→ `skills/oris-flow/references/fix.md`), architectural redesign, cross-feature refactors, DevOps, drive-by cleanup of code you did not touch.
@@ -27,26 +27,38 @@ The `oris-skills` CLI is NOT installed globally. ALWAYS invoke it as `npx oris-s
27
27
  ## Questions
28
28
 
29
29
  - ASK through the platform's question tool — Claude `AskUserQuestion`, Cursor `AskQuestion`
30
- (Plan Mode). A question turn = ONE call to it. Chat text is a fallback, NOT a choice: use
31
- it ONLY when no such tool is available (e.g. Cursor Agent Mode) or the question cannot fit
32
- the tool's schema (open-ended, or more options than it allows) then present the options
33
- as a lettered list.
30
+ whenever it is present in the current tool list. Never infer availability from the
31
+ platform mode. A question turn = ONE call to it. Chat text is a fallback, NOT a choice:
32
+ use it ONLY when no question tool is present or the question is open-ended.
34
33
  - Oris gates and interview questions ALWAYS qualify for the tool: the answer decides the
35
34
  next step. NEVER skip the tool because an answer "looks like a sensible default".
36
- - FIT the schema: question tools cap the options (typically 4, meta-options included).
37
- MORE options → split into a two-level question (category first) or use the deliberate
38
- text fallback above.
35
+ - FIT both platforms: every question has 2–4 explicit options, including meta-options.
36
+ MORE choices → split them into successive native questions; never flatten them to chat
37
+ text while the tool is present.
39
38
  - ONE question per turn. Recommended answer FIRST.
39
+ - VISIBILITY: assume the user sees ONLY what the question tool itself renders — chat text
40
+ emitted in the same turn as the tool call can be hidden by the platform UI. Therefore
41
+ everything the answer depends on rides INSIDE the call: the recap/context in the
42
+ `question` text (compact — counted facts, not prose), each option's meaning and
43
+ consequence in its description. NEVER put a recap or summary in chat text and then call
44
+ the question tool in the same turn — the user may see the bare question and nothing else.
40
45
  - ALWAYS include, in the user's language:
41
- - `Explain the options` / `Spiega le opzioni` — explain, then re-ask the same question.
46
+ - `Explain the options` / `Spiega le opzioni` — when picked, RE-ASK the same question
47
+ WITH the explanations embedded in the call itself: every option's description states
48
+ what it means and what happens if chosen; the `question` text may add one context
49
+ line. Re-asking the question unchanged, or explaining only in chat text before the
50
+ call, is a failure — the user reported seeing the bare question again. In text-fallback
51
+ menus: explanations first, then the full lettered list again, in ONE message.
42
52
  - During interviews: `Enough questions — proceed` / `Basta domande — procedi` (early exit → go to the generation gate; NOT approval to write).
43
53
  - NEVER ask what the workspace, docs, code, or setup map already answer. Explore first.
44
54
 
45
55
  ## Generation gates
46
56
 
47
57
  - Standard labels, localized: `Generate the document` / `Genera il documento`, `Approve document` / `Approva documento`, `Continue the interview` / `Continua l'intervista`, `Cancel` / `Annulla`.
48
- - NEVER write documents before the explicit gate choice. Exception: `oris-flow-criteria` writes first, then asks ONCE — the document is confirmed only on approval.
49
- - After a document is written: concise summary + contextual next-step menu. NEVER auto-start the next phase.
58
+ - NEVER write documents before the explicit gate choice. Exception: `skills/oris-flow/references/criteria.md` writes first, then asks ONCE — the document is confirmed only on approval.
59
+ - After a document is written: concise summary + contextual next-step menu. The summary
60
+ rides inside the next-step question (`## Questions` VISIBILITY rule) — never as chat
61
+ text the tool call can hide. NEVER auto-start the next phase.
50
62
 
51
63
  ## Language
52
64
 
@@ -17,6 +17,22 @@ function exists(relativePath) {
17
17
  return fs.existsSync(path.join(root, relativePath));
18
18
  }
19
19
 
20
+ function routeDestinations(text) {
21
+ return [...text.matchAll(/^\|\s*[a-z-]+\s*\|[^\n]*\|\s*`(skills\/oris-flow\/references\/[a-z-]+\.md)`\s*\|$/gm)]
22
+ .map((match) => match[1]);
23
+ }
24
+
25
+ function navigatorNodes(text) {
26
+ const nodes = new Map();
27
+ const matches = [...text.matchAll(/^### `([a-z-]+)`\r?\n([\s\S]*?)(?=^### `|^## |(?![\s\S]))/gm)];
28
+ for (const match of matches) {
29
+ const options = [...match[2].matchAll(/^- `[^`]+` → `(node|route|explain):([a-z-]+)`/gm)]
30
+ .map((option) => ({ type: option[1], target: option[2] }));
31
+ nodes.set(match[1], options);
32
+ }
33
+ return nodes;
34
+ }
35
+
20
36
  function runCli(args, homeDir) {
21
37
  return childProcess.spawnSync(process.execPath, ["scripts/oris-skills.mjs", ...args], {
22
38
  cwd: root,
@@ -40,18 +56,46 @@ test("plugin manifest skills all exist and match front-matter names", () => {
40
56
 
41
57
  test("oris-flow route table destinations exist and routing stays in-chat", () => {
42
58
  const text = read("skills/oris-flow/SKILL.md");
43
- const destinations = [...text.matchAll(/`(skills\/oris-flow\/references\/[a-z-]+\.md)`/g)].map((match) => match[1]);
44
- assert.ok(destinations.length >= 13, "route table must list at least 13 destinations");
59
+ const destinations = routeDestinations(text);
60
+ assert.equal(destinations.length, 16, "route table must list all 16 destinations");
45
61
  for (const destination of destinations) assert.equal(exists(destination), true, destination);
46
62
  assert.deepEqual(destinations, [...new Set(destinations)], "route destinations must be unique");
47
63
  assert.match(text, /NEVER tell the user to type another command/i);
48
64
  assert.match(text, /route to the interview owner/i);
49
65
  assert.match(text, /references\/conventions\.md/);
66
+ assert.match(text, /references\/question-navigator\.md/);
67
+ assert.doesNotMatch(text, /plain-text lettered list|present it as a plain-text/i);
68
+ });
69
+
70
+ test("question navigator covers every route within the portable option cap", () => {
71
+ const skill = read("skills/oris-flow/SKILL.md");
72
+ const navigator = read("skills/oris-flow/references/question-navigator.md");
73
+ const routes = routeDestinations(skill).map((destination) => path.basename(destination, ".md")).sort();
74
+ const nodes = navigatorNodes(navigator);
75
+ assert.ok(nodes.has("root"), "navigator starts at root");
76
+
77
+ const leaves = [];
78
+ for (const [name, options] of nodes) {
79
+ assert.ok(options.length >= 2 && options.length <= 4, `${name} has 2-4 options`);
80
+ assert.deepEqual(
81
+ options.filter((option) => option.type === "explain"),
82
+ [{ type: "explain", target: name }],
83
+ `${name} has one explain option returning to itself`,
84
+ );
85
+ for (const option of options) {
86
+ if (option.type === "node") assert.ok(nodes.has(option.target), `${name} targets existing node ${option.target}`);
87
+ if (option.type === "route") leaves.push(option.target);
88
+ }
89
+ }
90
+ assert.deepEqual(leaves.sort(), routes, "every route appears exactly once as a navigator leaf");
50
91
  });
51
92
 
52
93
  test("shared conventions centralize question, language, and gate rules", () => {
53
94
  const conventions = read("references/conventions.md");
54
95
  assert.match(conventions, /ONE question per turn/i);
96
+ assert.match(conventions, /whenever it is present in the current tool list/i);
97
+ assert.match(conventions, /2–4 explicit options/i);
98
+ assert.doesNotMatch(conventions, /Cursor Agent Mode|Cursor `AskQuestion`\s*\(Plan Mode\)/i);
55
99
  assert.match(conventions, /Explain the options.*Spiega le opzioni/s);
56
100
  assert.match(conventions, /NEVER write documents, code, settings, Git, or DevOps without explicit user confirmation/i);
57
101
  assert.match(conventions, /`Basta domande — procedi`/);
@@ -59,10 +103,17 @@ test("shared conventions centralize question, language, and gate rules", () => {
59
103
  assert.match(conventions, /`Continua l'intervista`/);
60
104
  assert.match(conventions, /`Approva documento`/);
61
105
  assert.match(conventions, /`Annulla`/);
62
- assert.match(conventions, /oris-flow-criteria.*writes first/i, "the criteria write-first exception must live where skills read it");
106
+ assert.match(conventions, /skills\/oris-flow\/references\/criteria\.md`.*writes first/i, "the criteria write-first exception must live where skills read it");
107
+ assert.doesNotMatch(conventions, /oris-flow-(criteria|implement|fix)/, "destinations are named by file path, never by prose nickname");
63
108
  assert.equal(exists("references/questions.md"), false, "questions.md was merged into conventions.md");
64
109
  });
65
110
 
111
+ test("package and plugin expose one release version", () => {
112
+ const packageJson = JSON.parse(read("package.json"));
113
+ const plugin = JSON.parse(read(".cursor-plugin/plugin.json"));
114
+ assert.equal(plugin.version, packageJson.version);
115
+ });
116
+
66
117
  test("every skill points at conventions instead of repeating shared rules", () => {
67
118
  const manifest = JSON.parse(read(".cursor-plugin/plugin.json"));
68
119
  for (const entry of manifest.skills) {
@@ -28,38 +28,56 @@ function markdownFiles(dir) {
28
28
  // A standalone skill (Claude/Cursor) has no bundle root above it, so every reference it
29
29
  // points to must resolve inside the skill folder — the regression that broke
30
30
  // `references/conventions.md` at runtime.
31
- test("installed Claude skill is self-contained", () => {
31
+ test("installed Cursor and Claude skills are self-contained and version-aligned", () => {
32
32
  const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), "oris-self-contained-"));
33
33
  try {
34
+ fs.mkdirSync(path.join(homeDir, ".cursor"), { recursive: true });
34
35
  fs.mkdirSync(path.join(homeDir, ".claude"), { recursive: true });
35
- const result = runCli(["install", "--force"], homeDir);
36
+ const result = runCli(["install", "--force", "--no-mcp", "--agents", "cursor,claude"], homeDir);
36
37
  assert.equal(result.status, 0, result.stderr);
37
38
 
38
- const skill = path.join(homeDir, ".claude", "skills", "oris-flow");
39
- assert.ok(fs.existsSync(skill), "oris-flow skill was installed");
39
+ const packageVersion = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")).version;
40
+ const installManifest = JSON.parse(
41
+ fs.readFileSync(path.join(homeDir, ".oris", "oris-skills", ".oris-skills-install.json"), "utf8"),
42
+ );
43
+ assert.equal(installManifest.version, packageVersion, "bundle manifest matches package version");
40
44
 
41
- // The shared references that used to dangle must now be present.
42
- for (const name of ["conventions.md", "doc-policy.md"]) {
43
- assert.ok(
44
- fs.existsSync(path.join(skill, "references", name)),
45
- `shared reference ${name} is bundled into the skill`,
46
- );
47
- }
45
+ for (const agent of ["cursor", "claude"]) {
46
+ const skill = path.join(homeDir, `.${agent}`, "skills", "oris-flow");
47
+ assert.ok(fs.existsSync(skill), `${agent} oris-flow skill was installed`);
48
+
49
+ for (const name of ["conventions.md", "doc-policy.md", "question-navigator.md"]) {
50
+ assert.ok(
51
+ fs.existsSync(path.join(skill, "references", name)),
52
+ `${agent} bundles ${name}`,
53
+ );
54
+ }
48
55
 
49
- const files = markdownFiles(skill);
50
- const pathToken = /(?:references|templates|agents)\/[A-Za-z0-9._/-]+\.(?:md|json|toml)/g;
51
- const missing = [];
52
- let bundlePrefixLeaks = 0;
53
- for (const file of files) {
54
- const text = fs.readFileSync(file, "utf8");
55
- // No bundle-root-relative pointer may survive in a standalone skill.
56
- if (text.includes("skills/oris-flow/")) bundlePrefixLeaks += 1;
57
- for (const cited of text.match(pathToken) ?? []) {
58
- if (!fs.existsSync(path.join(skill, cited))) missing.push(`${path.basename(file)} → ${cited}`);
56
+ const files = markdownFiles(skill);
57
+ const pathToken = /(?:references|templates|agents)\/[A-Za-z0-9._/-]+\.(?:md|json|toml)/g;
58
+ const missing = [];
59
+ let bundlePrefixLeaks = 0;
60
+ for (const file of files) {
61
+ const text = fs.readFileSync(file, "utf8");
62
+ if (text.includes("skills/oris-flow/")) bundlePrefixLeaks += 1;
63
+ for (const cited of text.match(pathToken) ?? []) {
64
+ if (!fs.existsSync(path.join(skill, cited))) missing.push(`${path.basename(file)} ${cited}`);
65
+ }
59
66
  }
67
+ assert.equal(bundlePrefixLeaks, 0, `${agent} has no bundle-root path leaks`);
68
+ assert.deepEqual(missing, [], `${agent} cited references resolve`);
69
+
70
+ const navigator = fs.readFileSync(path.join(skill, "references", "question-navigator.md"), "utf8");
71
+ const leaves = [...navigator.matchAll(/`route:([a-z-]+)`/g)].map((match) => match[1]);
72
+ assert.equal(leaves.length, 16, `${agent} navigator keeps all route leaves`);
73
+ for (const match of navigator.matchAll(/^### `([a-z-]+)`\r?\n([\s\S]*?)(?=^### `|^## |(?![\s\S]))/gm)) {
74
+ const options = match[2].match(/^- `[^`]+` → `/gm) ?? [];
75
+ assert.ok(options.length >= 2 && options.length <= 4, `${agent} ${match[1]} keeps 2-4 options`);
76
+ }
77
+
78
+ const marker = JSON.parse(fs.readFileSync(path.join(skill, ".oris-skills-managed.json"), "utf8"));
79
+ assert.equal(marker.version, packageVersion, `${agent} marker matches package version`);
60
80
  }
61
- assert.equal(bundlePrefixLeaks, 0, "no `skills/oris-flow/` paths remain in the standalone skill");
62
- assert.deepEqual(missing, [], "every cited reference resolves inside the skill");
63
81
  } finally {
64
82
  fs.rmSync(homeDir, { recursive: true, force: true });
65
83
  }
@@ -50,8 +50,9 @@ test("skill style: oris-flow", () => {
50
50
 
51
51
  test("every route reference carries the style and resolves its handles", () => {
52
52
  const skillText = fs.readFileSync(path.join(skillsRoot, "oris-flow", "SKILL.md"), "utf8");
53
- const routes = [...skillText.matchAll(/`skills\/oris-flow\/references\/([a-z-]+\.md)`/g)].map((match) => match[1]);
54
- assert.ok(routes.length >= 13, `router table lists all routes (found ${routes.length})`);
53
+ const routes = [...skillText.matchAll(/^\|\s*[a-z-]+\s*\|[^\n]*\|\s*`skills\/oris-flow\/references\/([a-z-]+\.md)`\s*\|$/gm)]
54
+ .map((match) => match[1]);
55
+ assert.equal(routes.length, 16, `router table lists all routes (found ${routes.length})`);
55
56
  assert.deepEqual(routes, [...new Set(routes)], "route destinations are unique");
56
57
  const referencesDir = path.join(skillsRoot, "oris-flow", "references");
57
58
  for (const file of routes) {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oris-flow
3
- description: The one Oris skill - read the intent, pick ONE route, apply it in the same chat. Routes setup, new project, discovery, acceptance criteria, technical plan, implement, fix, verify, spec change, architecture review, docs, commit, pull request, and help.
3
+ description: The one Oris skill - read the intent, pick ONE route, apply it in the same chat. Routes setup, new, triage, discover, criteria, plan, implement, fix, verify, change, architecture, docs, commit, pr, handoff, and help.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -23,6 +23,7 @@ Match the desired outcome to ONE route, then apply its reference:
23
23
  |-------|----------------------|-------|
24
24
  | setup | prepare / map / refresh an existing repo for Oris and agents | `skills/oris-flow/references/setup.md` |
25
25
  | new | bootstrap a project from scratch, greenfield, empty directory | `skills/oris-flow/references/new.md` |
26
+ | triage | capture an idea, bug report, or request as a work item with an agent-ready brief | `skills/oris-flow/references/triage.md` |
26
27
  | discover | understand or define product behavior, functional analysis | `skills/oris-flow/references/discover.md` |
27
28
  | criteria | acceptance criteria, QA checks, testable scenarios | `skills/oris-flow/references/criteria.md` |
28
29
  | plan | a technical implementation plan before coding | `skills/oris-flow/references/plan.md` |
@@ -34,6 +35,7 @@ Match the desired outcome to ONE route, then apply its reference:
34
35
  | docs | update task docs after a change | `skills/oris-flow/references/docs.md` |
35
36
  | commit | commit changes with the Oris standard — Conventional Commits, work item linked | `skills/oris-flow/references/commit.md` |
36
37
  | pr | open or update a pull request, English title/description linked to the work item | `skills/oris-flow/references/pr.md` |
38
+ | handoff | package session state — decisions, evidence, next move — to resume in a fresh session | `skills/oris-flow/references/handoff.md` |
37
39
  | help | how Oris works, install, update, troubleshooting | `skills/oris-flow/references/help.md` |
38
40
 
39
41
  ## Precedence (the calls that look ambiguous)
@@ -43,37 +45,23 @@ Match the desired outcome to ONE route, then apply its reference:
43
45
  2. RETHINK beats build: analyze, question, or reshape existing work →
44
46
  route to the interview owner (discover / plan / change), NEVER straight to implement.
45
47
  3. CHANGED spec on a feature that already has task docs or code → change, not discover —
46
- change owns the delta and the history.
47
- 4. BROKEN behaviorfix. NEW planned work → implement. The menu answer "Implement or
48
- fix" gets exactly one follow-up question to split them.
48
+ change owns the delta and the history. Spec unchanged but code/reality moved on and the
49
+ task docs lag behind docs, not change.
50
+ 4. BROKEN behavior fix. NEW planned work → implement.
49
51
  5. EMPTY directory or from-scratch intent → new. Existing repo never touched by Oris
50
52
  (no `AGENTS.md`, no `.oris-flow/`) → recommend setup first; respect the user's choice.
51
53
  6. COMMIT staged/working changes with the standard → commit. OPEN or update a pull request
52
54
  → pr. Neither writes product code — they package and publish what implement/fix produced.
55
+ 7. CAPTURE work for later (an idea, a report, backlog intake) → triage — it creates the
56
+ work item and stops. DOING the work now → discover / fix / implement.
57
+ 8. CONTINUE elsewhere — session ending, context full, "pass this to another agent" →
58
+ handoff.
53
59
 
54
- ## Menu (low confidence)
60
+ ## Low-confidence navigator
55
61
 
56
- ASK "What do you want to do?" in the user's language. This menu exceeds every
57
- question tool's option cap present it as a plain-text lettered list (the deliberate
58
- fallback in `references/conventions.md` `## Questions`), options:
59
-
60
- - Setup repository
61
- - New project from scratch
62
- - Understand / define behavior (discovery)
63
- - Acceptance criteria
64
- - Technical plan
65
- - Implement or fix
66
- - Verify acceptance criteria
67
- - Spec changed: update feature docs
68
- - Architecture review
69
- - Update docs
70
- - Commit changes
71
- - Open a pull request
72
- - Help
73
- - Explain the options / Spiega le opzioni
74
-
75
- IF "Explain the options" → explain briefly, re-ask the same question.
76
- Every other label maps 1:1 to its route in the table above.
62
+ IF intent is unclear READ `skills/oris-flow/references/question-navigator.md` and APPLY
63
+ it in the same chat. It owns the native, outcome-based route selection; the router does
64
+ not carry or flatten its menu.
77
65
 
78
66
  ## Never
79
67
 
@@ -81,9 +69,9 @@ Every other label maps 1:1 to its route in the table above.
81
69
  - Write anything — the route's reference owns every gate.
82
70
  - Hand the user a command or skill name to type — enter the route yourself.
83
71
  - Route to implement while the plan itself is in question.
84
- - Keep interviewing here: one menu question maximum, then enter.
72
+ - Keep interviewing here: unclear intent belongs to the question navigator.
85
73
 
86
74
  ## Done when
87
75
 
88
- - [ ] One route entered and applied in the same chat, or the menu was asked exactly once.
76
+ - [ ] One route entered and applied in the same chat.
89
77
  - [ ] No writes happened before the route's own gate.
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Oris Flow"
3
- short_description: "Start the Oris workflow menu"
4
- default_prompt: "Use $oris-flow to choose the right Oris workflow command."
3
+ short_description: "Route, build, and verify with Oris"
4
+ default_prompt: "Use $oris-flow to enter the right Oris route."
@@ -37,10 +37,13 @@ WRITE a self-contained HTML file to the OS temp dir (`architecture-review-<times
37
37
  OPEN it (`start` | `open` | `xdg-open`), TELL the absolute path.
38
38
 
39
39
  FORMAT: Tailwind CDN + Mermaid CDN. Per candidate, one card:
40
- - title (names the deepening) + strength badge: `Strong` | `Worth exploring` | `Speculative`;
40
+ - title (names the deepening) + strength badge `Strong` (friction observed in the code,
41
+ fix shape clear) | `Worth exploring` (friction observed, fix shape uncertain) |
42
+ `Speculative` (pattern suggests it, not yet observed);
41
43
  - files (monospaced), Problem (one sentence), Solution (one sentence);
42
44
  - Before/After diagram side by side — Mermaid for graph-shaped, hand-built divs/SVG for
43
- mass diagrams; if the diagram needs a paragraph, redraw the diagram;
45
+ mass diagrams; the diagram must explain itself without a caption if it needs one,
46
+ simplify the diagram;
44
47
  - wins as bullets ≤6 words, glossary terms only — never "cleaner code";
45
48
  - ADR conflict → amber callout ("contradicts ADR-0007 — worth reopening because…").
46
49
 
@@ -3,6 +3,9 @@
3
3
  Specs changed while the feature exists (documented, planned, or half-built). Understand
4
4
  the delta, update EVERYTHING together, keep the history traceable.
5
5
 
6
+ BOUNDARY: the business spec MOVED → this route. Spec unchanged but code/reality moved on
7
+ and the docs lag behind → `skills/oris-flow/references/docs.md`.
8
+
6
9
  RULES: `references/conventions.md`. Doc standards: `references/doc-policy.md`.
7
10
 
8
11
  ## Delta interview
@@ -12,9 +12,13 @@ RULES: `references/conventions.md`. Doc standards: `references/doc-policy.md`.
12
12
  preferred, never required — say once when missing) > current UI > code and tests.
13
13
  2. DEDUCE create vs update: existing `acceptance-criteria.md` → update, PRESERVE IDs.
14
14
  3. IDs: `AC-001`, `AC-002`, … stable across revisions.
15
- 4. Each scenario declares ALL of: role + starting state · deterministic data · numbered
16
- user steps · observable outcome under the step that causes it · negative coverage ·
17
- regressions to keep.
15
+ 4. Each scenario declares ALL of:
16
+ - role + starting state;
17
+ - deterministic data;
18
+ - numbered user steps;
19
+ - observable outcome under the step that causes it;
20
+ - negative coverage;
21
+ - regressions to keep.
18
22
  5. CLASSIFY each: `Verifiable` | `Needs setup/data` | `Blocked by Open QA`.
19
23
  6. DISCARD criteria not checkable through observable product behavior. Unbuilt features:
20
24
  only confirmed intended behavior.
@@ -3,6 +3,9 @@
3
3
  Bring `{tasksRoot}/{task}/` documents in line with a later change, keeping the change
4
4
  traceable ({tasksRoot} per doc-policy).
5
5
 
6
+ BOUNDARY: the spec is unchanged but code/reality moved on → this route. The business spec
7
+ itself changed → `skills/oris-flow/references/change.md` (it owns the delta and the history).
8
+
6
9
  RULES: `references/conventions.md`. Doc standards: `references/doc-policy.md`.
7
10
 
8
11
  ## Workflow
@@ -18,7 +21,8 @@ RULES: `references/conventions.md`. Doc standards: `references/doc-policy.md`.
18
21
  - add one change-history row per document: date | source | short change | reason;
19
22
  - keep unresolved risks in open points;
20
23
  - preserve acceptance-criteria IDs.
21
- 7. CLOSE with a concise summary. Offer next steps without auto-starting them.
24
+ 7. CLOSE with a concise summary. OFFER next: commit the doc updates
25
+ (`skills/oris-flow/references/commit.md`) | stop — never auto-started.
22
26
 
23
27
  ## Never
24
28
 
@@ -5,7 +5,7 @@ any edit, evidence before done.
5
5
 
6
6
  RULES: `references/conventions.md`. Research: `references/research.md`.
7
7
 
8
- ## Triage
8
+ ## Intake
9
9
 
10
10
  1. IF no details given → ask ONE question: what happens, what was expected, where
11
11
  (link/ID when one exists).
@@ -37,7 +37,8 @@ RULES: `references/conventions.md`. Research: `references/research.md`.
37
37
  1. RUN the reproduction + targeted tests; broaden if the surface is shared.
38
38
  2. SUMMARIZE: cause, change, verification, residual risk.
39
39
  3. RECOMMEND: `skills/oris-flow/references/verify.md` when criteria exist; docs update
40
- (`skills/oris-flow/references/docs.md`) when documented behavior changed.
40
+ (`skills/oris-flow/references/docs.md`) when documented behavior changed; commit
41
+ (`skills/oris-flow/references/commit.md`) when the fix is verified and ready to package.
41
42
 
42
43
  ## Never
43
44
 
@@ -0,0 +1,67 @@
1
+ # Handoff
2
+
3
+ Package this session's state so the next session — or another agent — resumes from the
4
+ exact point: decisions, evidence, next move. The handoff is a bridge, not a store: task
5
+ docs and `AGENTS.md` stay the truth, the handoff points at them and carries ONLY what
6
+ lives nowhere else yet.
7
+
8
+ RULES: `references/conventions.md`. Entering handoff IS the request to write it — no
9
+ generation gate; the document lands outside the repo.
10
+
11
+ ## 1. Collect (silent)
12
+
13
+ 1. GATHER from this conversation: the active task and route, decisions the user
14
+ confirmed, evidence observed (commands seen green, verifications, reproductions),
15
+ open questions with their current best answer, and the next move.
16
+ 2. SPLIT what you gathered:
17
+ - already recorded in task docs or `AGENTS.md` → the handoff POINTS at the file;
18
+ - confirmed in chat but written nowhere → the handoff CARRIES it, marked with who
19
+ confirmed it;
20
+ - speculation → out, or listed as an open question.
21
+ 3. Durable project facts proved this session and missing from `AGENTS.md` → write them
22
+ back NOW (`references/conventions.md` `## Project facts`), so the handoff can point
23
+ instead of carry.
24
+
25
+ ## 2. Write (outside the repo)
26
+
27
+ WRITE `handoff-{task-or-topic}-{timestamp}.md` to the OS temp directory — never inside
28
+ the repo or `{tasksRoot}`. Language: `artifactLanguage` (another session reads this cold —
29
+ never caveman-compressed). Structure:
30
+
31
+ ```markdown
32
+ # Handoff — {task or topic}
33
+ Date: … | Repo: {absolute path} | Route in progress: {route or none}
34
+ ## Where we are
35
+ What was asked, what is done, what is verified — evidence, not claims.
36
+ ## Decisions confirmed in chat, not yet in docs
37
+ - {decision} — confirmed by {user}, because {reason}
38
+ ## Read before acting
39
+ - {file} — {why it matters first}
40
+ ## Open questions
41
+ - {question} — current best answer: {answer or none}
42
+ ## Next move
43
+ One imperative sentence: the first action the next session takes.
44
+ ## Resume with
45
+ {the route reference to re-enter} — {one-line why}
46
+ ```
47
+
48
+ TELL the absolute path + a one-line summary of the next move. OFFER: keep working here |
49
+ stop.
50
+
51
+ ## Never
52
+
53
+ - Write the handoff inside the repo or under `{tasksRoot}` — it is session luggage, not
54
+ a project document.
55
+ - Duplicate task-doc or `AGENTS.md` content — point at the file.
56
+ - Carry anything not observed in this session or confirmed by the user — a handoff that
57
+ guesses poisons the next session.
58
+ - Include secrets or tokens — mask as `***`.
59
+ - Auto-start the next route after writing.
60
+
61
+ ## Done when
62
+
63
+ - [ ] Facts proved this session written back to `AGENTS.md` before the handoff.
64
+ - [ ] Every item in the handoff is a pointer, an observed fact, or a user-confirmed
65
+ decision — nothing guessed.
66
+ - [ ] Document written to the OS temp dir; absolute path and next move shown.
67
+ - [ ] Resume route named; nothing auto-started.
@@ -12,6 +12,8 @@ details on request.
12
12
  | Copilot / any other agent | Copilot Chat: enable `chat.promptFiles` once, then `/oris-flow`. Anything else that reads files: point it at `~/.oris/oris-flow.md`. |
13
13
  | Uninstall / reinstall | `npx oris-skills uninstall` / `npx oris-skills reinstall` (preview with `--dry-run`). |
14
14
  | Skill missing after install | Reload the agent; check `~/.oris/oris-skills/` exists; re-run install with `--force`. |
15
+ | Capture an idea or bug without doing it now | `/oris-flow` → Triage — it becomes a work item with a brief, routed to its route. |
16
+ | Context window full / continue in a new session | `/oris-flow` → Hand off — writes a resume doc and names the route to re-enter. |
15
17
  | Change document language / chat verbosity | `/oris-flow` → Setup (settings live in `.oris-flow/settings.json`). |
16
18
  | Ultra-short answers | `/oris-flow` → Setup → set `responseStyle: caveman` — chat shrinks to maximum token density; documents stay complete. |
17
19
 
@@ -34,7 +34,8 @@ RULES: `references/conventions.md`. Research: `references/research.md`.
34
34
  1. RUN targeted verification first; broaden when the touched surface is shared.
35
35
  2. SUMMARIZE: touched files, verification results, residual risk.
36
36
  3. RECOMMEND next: `skills/oris-flow/references/verify.md` when acceptance criteria exist;
37
- otherwise update docs (`skills/oris-flow/references/docs.md`).
37
+ otherwise update docs (`skills/oris-flow/references/docs.md`) or commit
38
+ (`skills/oris-flow/references/commit.md`) when the change is verified and ready to package.
38
39
 
39
40
  ## Never
40
41
 
@@ -22,8 +22,8 @@ RULES: `references/conventions.md`. DevOps config: `references/devops.md`.
22
22
  ## Gate (never skipped)
23
23
 
24
24
  SHOW the title + description + target branch. ASK: open PR | edit | cancel.
25
- ON open → create via the provider (Azure DevOps MCP `oris-devops`, or `gh` for GitHub)
26
- read from `references/devops.md`. Missing provider auth → say so; never guess credentials.
25
+ ON open → create via the configured provider (`references/devops.md` read `provider`,
26
+ act generically). Missing provider auth → say so; never guess credentials.
27
27
 
28
28
  ## After
29
29
 
@@ -0,0 +1,82 @@
1
+ # Question Navigator
2
+
3
+ Choose one route when the user's intent is unclear. This is a deep routing module, not
4
+ a route: selecting a leaf enters that route in the same chat.
5
+
6
+ RULES: `references/conventions.md`.
7
+
8
+ ## Protocol
9
+
10
+ START at `root`. ASK exactly the options of the current node through the platform's
11
+ question tool. A `node:` target opens that node; a `route:` target enters the referenced
12
+ route immediately.
13
+
14
+ IF no question tool is present → show only the current node as a lettered list, accept
15
+ one answer, then continue through the same tree. Never flatten multiple nodes.
16
+
17
+ IF `explain` is selected → re-ask the same node with every option's description and
18
+ consequence visible inside the question call.
19
+
20
+ ## Tree
21
+
22
+ ### `root`
23
+ - `Understand or decide` → `node:understand` — Clarify behavior, code, or planned work.
24
+ - `Build or verify` → `node:build` — Implement, repair, or check real behavior.
25
+ - `Manage or deliver` → `node:manage` — Start, document, publish, continue, or get help.
26
+ - `Explain the options` → `explain:root` — Describe these groups, then re-ask this node.
27
+
28
+ ### `understand`
29
+ - `Understand behavior` → `node:behavior` — Define, test, or change product behavior.
30
+ - `Decide the solution` → `node:solution` — Plan implementation or review architecture.
31
+ - `Capture work for later` → `route:triage` — Create an agent-ready work item without doing it.
32
+ - `Explain the options` → `explain:understand` — Describe these outcomes, then re-ask this node.
33
+
34
+ ### `behavior`
35
+ - `Define desired behavior` → `route:discover` — Interview and document product behavior.
36
+ - `Define acceptance criteria` → `route:criteria` — Write testable business scenarios.
37
+ - `Update a changed specification` → `route:change` — Apply a confirmed behavior delta.
38
+ - `Explain the options` → `explain:behavior` — Describe these routes, then re-ask this node.
39
+
40
+ ### `solution`
41
+ - `Create a technical plan` → `route:plan` — Produce an execution-ready implementation plan.
42
+ - `Review architecture` → `route:architecture` — Find deepening and refactor opportunities.
43
+ - `Explain the options` → `explain:solution` — Describe these routes, then re-ask this node.
44
+
45
+ ### `build`
46
+ - `Implement planned work` → `route:implement` — Build from a plan or confirmed scope.
47
+ - `Fix broken behavior` → `route:fix` — Diagnose and repair a regression or failed check.
48
+ - `Verify acceptance criteria` → `route:verify` — Check criteria against the real product.
49
+ - `Explain the options` → `explain:build` — Describe these routes, then re-ask this node.
50
+
51
+ ### `manage`
52
+ - `Start or prepare a project` → `node:start` — Bootstrap or map a repository.
53
+ - `Document or deliver work` → `node:deliver` — Update docs, commit, or open a pull request.
54
+ - `Continue or get help` → `node:continue` — Transfer context or troubleshoot Oris.
55
+ - `Explain the options` → `explain:manage` — Describe these outcomes, then re-ask this node.
56
+
57
+ ### `start`
58
+ - `New project from scratch` → `route:new` — Bootstrap an empty or scaffold-only repository.
59
+ - `Set up an existing repository` → `route:setup` — Map an existing repository for Oris.
60
+ - `Explain the options` → `explain:start` — Describe these routes, then re-ask this node.
61
+
62
+ ### `deliver`
63
+ - `Update task documentation` → `route:docs` — Align task docs with current reality.
64
+ - `Commit changes` → `route:commit` — Package changes with the Oris Git standard.
65
+ - `Open or update a pull request` → `route:pr` — Publish the branch for review.
66
+ - `Explain the options` → `explain:deliver` — Describe these routes, then re-ask this node.
67
+
68
+ ### `continue`
69
+ - `Hand off this session` → `route:handoff` — Package state for another session or agent.
70
+ - `Get Oris help` → `route:help` — Explain installation, usage, or troubleshooting.
71
+ - `Explain the options` → `explain:continue` — Describe these routes, then re-ask this node.
72
+
73
+ ## Never
74
+
75
+ - Ask about a route the user's clear intent already selected.
76
+ - Present options from more than one node in a single question.
77
+ - Enter two routes, or stop between a leaf selection and its route.
78
+
79
+ ## Done when
80
+
81
+ - [ ] One leaf selected through native questions, or the same node-by-node text fallback.
82
+ - [ ] The selected route entered in the same chat.
@@ -5,7 +5,8 @@ preferences in `.oris-flow/settings.json`, AI-readiness checked. ADAPT to what t
5
5
  IS; never force one structure. Writes ONLY after the user confirms the recap.
6
6
 
7
7
  RULES: `references/conventions.md`. Settings: `references/settings.md`.
8
- IF the repo is empty or brand-new → route to `skills/oris-flow/references/new.md` instead.
8
+ IF the repo has no source files, or no commit beyond a scaffold-only init → route to
9
+ `skills/oris-flow/references/new.md` instead.
9
10
 
10
11
  ## Mode
11
12
 
@@ -28,9 +29,9 @@ ELSE → create from scratch.
28
29
  4. FAN OUT parallel subagent scans (docs, frontend, backend/data, tests/build, local
29
30
  skills/rules) by DEFAULT whenever the repo has more than one of those areas —
30
31
  entering setup is the user's request to spawn (`references/conventions.md`
31
- `## Subagents`). SKIP only when the repo is small enough that the baseline already
32
- answers every §2 decision — say you skipped and why. No agent tool on the platform →
33
- same scans inline, sequentially.
32
+ `## Subagents`). SKIP only when the baseline scan already answers EVERY §2 decision
33
+ (project type, tasks root, verify commands, version control) — say you skipped and
34
+ name the evidence. No agent tool on the platform → same scans inline, sequentially.
34
35
 
35
36
  ## 2. Present findings, decide one at a time
36
37
 
@@ -0,0 +1,69 @@
1
+ # Triage
2
+
3
+ Turn raw intake — an idea, a bug report, a request — into a work item on the DevOps
4
+ provider with a brief the next route can act on. Capture, classify, route: the work
5
+ itself stays with discover / fix / implement.
6
+
7
+ RULES: `references/conventions.md`. Provider: `references/devops.md`.
8
+
9
+ ## 1. Understand the intake
10
+
11
+ 1. READ the resolved DevOps config (`references/devops.md`). Provider tools missing or
12
+ unauthenticated → degrade: compose everything below, show it, tell the user where to
13
+ paste it — never block on tooling.
14
+ 2. SEARCH the provider for existing work items matching the intake (title, keywords,
15
+ area) BEFORE composing anything. A match → propose linking/updating it, never a
16
+ duplicate.
17
+ 3. CLASSIFY on evidence: bug (behavior observed broken) | feature (new behavior) |
18
+ spec change on an existing feature | chore. Cheap checks against the repo or product
19
+ come before questions; a claim you could verify and didn't stays a claim.
20
+ 4. ASK one question at a time, only for gaps evidence cannot close: expected vs actual,
21
+ reproduction conditions, desired outcome, urgency. Early exit always available.
22
+
23
+ ## 2. Compose the work item
24
+
25
+ BUILD title + description (language `artifactLanguage`; title says the behavior, not the
26
+ solution). Description carries the brief:
27
+
28
+ ```markdown
29
+ ## Intake
30
+ {verbatim request} — source: {who/where}, date: {date}
31
+ ## Type & evidence
32
+ {bug|feature|spec change|chore} — {what was checked, what was observed}
33
+ ## Expected vs actual ← bugs; features: ## Desired outcome
34
+
35
+ ## Reproduction ← bugs only
36
+ 1. …
37
+ ## Links
38
+ {duplicates found, related items, task docs if any}
39
+ ## Next step
40
+ {the Oris route that should pick this up}
41
+ ```
42
+
43
+ Spec change on a feature that already has task docs → say so: the delta belongs to
44
+ `skills/oris-flow/references/change.md`; the work item only tracks it.
45
+
46
+ ## 3. Gate, write, route
47
+
48
+ 1. SHOW the composed work item compactly (or the update to the existing one).
49
+ 2. ASK ONE question: Create the work item | Adjust | Stop. Update case: Update the
50
+ existing item | Adjust | Stop.
51
+ 3. ON approval → write via the provider; SHOW the id in the provider's `workItemSyntax`.
52
+ Degraded mode → deliver the composed item as text instead.
53
+ 4. OFFER next: enter the route named in the brief now | triage another intake | stop.
54
+
55
+ ## Never
56
+
57
+ - Do the work here — no code, no task docs; triage captures and routes.
58
+ - Write to the provider before the composed item is explicitly approved.
59
+ - Recreate what exists — search first; duplicates get linked or updated.
60
+ - Invent reporter, urgency, or behavior not present in the intake or observed.
61
+ - Put secrets, tokens, or personal data beyond the reporter's name in a work item.
62
+
63
+ ## Done when
64
+
65
+ - [ ] Intake classified with named evidence; duplicate search ran before composing.
66
+ - [ ] Work item shown and explicitly approved before any provider write.
67
+ - [ ] Work item created/updated with id shown in `workItemSyntax` — or degraded output
68
+ delivered and said so.
69
+ - [ ] Next route offered, not auto-started.
@@ -41,6 +41,7 @@ Date: … | Source: acceptance-criteria.md | Verified by: oris-flow verify route
41
41
 
42
42
  ON fix → enter `skills/oris-flow/references/fix.md` with the failing AC as the bug report;
43
43
  re-verify the fixed criteria afterwards, as many fix-verify passes as the user approves.
44
+ ON save with every AC Pass → also offer commit (`skills/oris-flow/references/commit.md`).
44
45
 
45
46
  ## Never
46
47