docs: place Office warnings within feature sections (#1764)
* docs: place Office warnings within feature sections * test(docs): cover substantive status sections * docs: attach experimental badges to Office features * test(docs): cover callouts without section headings
This commit is contained in:
@@ -34,13 +34,15 @@ The docs header renders a visible status callout from that frontmatter. To invok
|
||||
Use a section-level indicator when a stable guide contains one experimental capability. Keep this source syntax as Markdown so older renderers and GitHub still show an explicit callout; the publication layer upgrades it to the styled status component:
|
||||
|
||||
```markdown
|
||||
## Office status
|
||||
## Office dependencies
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office is disabled by default and its public workflow is not stable yet.
|
||||
> Office is feature-flagged and its dependency editor is not stable yet.
|
||||
|
||||
When Office is enabled, it can record blocked-by relationships between tasks. Use parent/child structure and workflow gates for the supported regular-Kanban path.
|
||||
```
|
||||
|
||||
Keep the indicator next to the relevant heading and explain the enabling condition, current limit, and supported alternative. The publication pipeline converts the callout to `FeatureStatus` and opts the generated page into MDX automatically.
|
||||
Place the indicator immediately after a descriptive heading that names the experimental capability, then follow it with the instructions or behavior it qualifies. Explain the enabling condition, current limit, and supported alternative. Do not drop a warning between otherwise stable paragraphs or create a standalone status section whose only content is the warning. The publication pipeline converts the callout to `FeatureStatus` and opts the generated page into MDX automatically.
|
||||
|
||||
## Add a page
|
||||
|
||||
|
||||
@@ -118,16 +118,11 @@ Kandev does not validate a server-name syntax centrally, so blank or unusual nam
|
||||
Deleting a profile is irreversible. Kandev checks references before deletion:
|
||||
|
||||
- active sessions and watcher references are soft conflicts; force bypasses the active-session check and soft-deletes the profile, while disabling affected watchers is best effort rather than guaranteed cleanup;
|
||||
- experimental Office routing-tier references are hard conflicts and cannot be forced;
|
||||
- feature-flagged Office routing-tier references are hard conflicts and cannot be forced;
|
||||
- Kandev attempts to clean every ephemeral task with a session using the profile, including matching Quick Chat, Configuration Chat, and Run-mode automation work. A cleanup failure is logged and does not prevent profile deletion, so audit leftover resources afterward.
|
||||
|
||||
Only custom TUI agents can be deleted from the agent list. Built-in definitions remain registered even when their CLI is not installed.
|
||||
|
||||
## Office status
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office team roles, reporting lines, budgets, concurrency, and governance add more fields to agent profiles only when the Office feature is enabled. Office is disabled by default and remains in progress; its coordinator routing and approval policy are not a stable public workflow. Regular profiles, workflow approval steps, and task-mode automation provide the supported human-gated path today.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Agent unavailable after install:** confirm the executable as Kandev's service user, select **Rescan**, and compare the service `PATH` with your shell.
|
||||
|
||||
@@ -196,11 +196,6 @@ The backend's `/mcp`, `/mcp/sse`, and `/mcp/message` routes currently have no Ka
|
||||
- Ensure the proxy protects both Streamable HTTP and SSE/message paths and permits long-lived requests.
|
||||
- Scope integration, Git, and agent credentials for the damage an unattended client could cause.
|
||||
|
||||
## Office status
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office has separate coordinator agents, routines, governance approvals, and an Office MCP/agentctl interface only when its feature flag is enabled. Office is disabled by default and remains in progress; do not treat its coordinator-led automation as a stable public contract. Workspace automations plus workflow approval/review steps are the supported human-gated mechanism today.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **No scheduled run:** use a preset or `@every`; fixed calendar cron and timezone scheduling are not implemented.
|
||||
|
||||
@@ -18,11 +18,6 @@ Kandev can coordinate several agents without turning every unit of work into a s
|
||||
|
||||
Shared files make handoff cheap but allow concurrent edits to collide. Separate environments isolate file state, but only the executor determines whether host processes and credentials are also isolated.
|
||||
|
||||
## Office status
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office is in progress and feature-flagged. Persistent coordinator teams, arbitrary-depth task trees, dependency properties, labels, named documents, reviewer/approver quorum, routines, and budgets are not stable regular-Kanban capabilities.
|
||||
|
||||
## Run parallel sessions in one task
|
||||
|
||||
Use an additional session when agents need the same task, repository attachments, and materialized environment.
|
||||
@@ -197,11 +192,14 @@ The coordinator has only the tools, filesystem access, credentials, and permissi
|
||||
|
||||
A human-led flow uses the same primitives but keeps **Do nothing** transitions at planning, review, or release steps. Humans can create each task, approve agent-proposed subtasks, restrict credentials to narrow profiles, and decide what merges or ships.
|
||||
|
||||
### Dependencies and Office
|
||||
### Office dependencies and deeper coordination
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office is feature-flagged, disabled in the production profile by default, and still in progress. Its dependency editor, persistent coordinators, deeper task trees, quorum rules, and routines are not stable regular-Kanban features.
|
||||
|
||||
Regular Kanban does not currently expose a dependency editor or blocker filter. Stored blocker data can appear through related-task MCP, but it is not a regular-board planning surface. For supported ordering, use parent/child structure, **When Child Tasks Complete**, explicit messages, workflow gates, and pull-request review.
|
||||
|
||||
Office prototypes **Blocked by** and **Blocking** properties with same-workspace, self-reference, and cycle validation, plus persistent coordinators and deeper trees. Office remains in progress; do not rely on these properties or its advanced quorum/routine behavior for a stable Kanban workflow.
|
||||
When Office is enabled, it prototypes **Blocked by** and **Blocking** properties with same-workspace, self-reference, and cycle validation. Treat these as an evaluation surface rather than a production coordination contract.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -21,11 +21,6 @@ A task is the unit of work. A workflow is the ordered process that task follows.
|
||||
|
||||
Workflow position and runtime state are different. Moving a card changes its workflow step; it does not prove that an agent ran, code was committed, review passed, or a pull request merged.
|
||||
|
||||
## Office status
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office is in progress and feature-flagged. Its persistent agents, arbitrary-depth task trees, blocker and label properties, named task documents, reviewer/approver quorum, routines, and budgets are not stable features of the regular Kanban task experience.
|
||||
|
||||
## Prepare a workspace
|
||||
|
||||
A new workspace created by a user does not automatically receive a workflow.
|
||||
@@ -196,7 +191,10 @@ Agents use `create_task_plan_kandev`, `get_task_plan_kandev`, `update_task_plan_
|
||||
|
||||
Revision history is not an immutable record of every autosave. Consecutive writes from the same author name and author kind coalesce into the latest revision for five minutes by default. Operators can set `KANDEV_PLAN_COALESCE_WINDOW_MS`; `0` disables coalescing, while an invalid or negative value falls back to five minutes.
|
||||
|
||||
### Current availability of documents, labels, and blockers
|
||||
## Office documents, labels, and blockers
|
||||
|
||||
> [!EXPERIMENTAL]
|
||||
> Office is feature-flagged, disabled in the production profile by default, and still in progress. Its named documents, labels, and blocker controls are not stable regular-Kanban features.
|
||||
|
||||
| Capability | Regular Kanban | Office |
|
||||
|---|---|---|
|
||||
|
||||
@@ -29,6 +29,7 @@ export async function validatePublicDocs(docsDir = defaultDocsDir) {
|
||||
|
||||
assertFrontmatter(file, markdown);
|
||||
assertDocumentStructure(file, markdown);
|
||||
assertExperimentalCalloutPlacement(file, markdown);
|
||||
|
||||
const slug = file.replace(/\.mdx?$/, "").replace(/\/index$/, "");
|
||||
const existing = pagesBySlug.get(slug);
|
||||
@@ -835,6 +836,61 @@ function assertDocumentStructure(file, markdown) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep experimental callouts attached to an explicit feature section.
|
||||
* A section-level indicator is the first content under its heading, followed
|
||||
* by the documentation it qualifies.
|
||||
*
|
||||
* @param {string} file Relative page path used in validation errors.
|
||||
* @param {string} markdown Page source.
|
||||
* @returns {void}
|
||||
*/
|
||||
function assertExperimentalCalloutPlacement(file, markdown) {
|
||||
const source = stripMarkdownCode(markdown);
|
||||
const headings = [...source.matchAll(/^(#{2,6})\s+([^\n]+?)\s*$/gm)];
|
||||
const callouts = [...source.matchAll(/^>\s*\[!EXPERIMENTAL\]\s*$/gim)];
|
||||
|
||||
for (const callout of callouts) {
|
||||
const headingIndex = headings.findLastIndex(
|
||||
(candidate) => candidate.index < callout.index,
|
||||
);
|
||||
const heading = headings[headingIndex];
|
||||
if (
|
||||
!heading ||
|
||||
source
|
||||
.slice(heading.index + heading[0].length, callout.index)
|
||||
.trim()
|
||||
) {
|
||||
throw new Error(
|
||||
`${file} experimental callouts must immediately follow a descriptive heading`,
|
||||
);
|
||||
}
|
||||
|
||||
const title = heading[2].trim();
|
||||
const level = heading[1].length;
|
||||
const nextHeading = headings
|
||||
.slice(headingIndex + 1)
|
||||
.find((candidate) => candidate[1].length <= level);
|
||||
const sectionEnd = nextHeading?.index ?? source.length;
|
||||
const calloutBlock = source
|
||||
.slice(callout.index)
|
||||
.match(
|
||||
/^>\s*\[!EXPERIMENTAL\]\s*\r?\n(?:^>.*(?:\r?\n|$))*/im,
|
||||
)?.[0];
|
||||
const sectionContent = source
|
||||
.slice(
|
||||
callout.index + (calloutBlock?.length ?? callout[0].length),
|
||||
sectionEnd,
|
||||
)
|
||||
.trim();
|
||||
if (!sectionContent) {
|
||||
throw new Error(
|
||||
`${file} has an experimental callout without substantive section content: ${title}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Require every relative Markdown link or image to resolve on disk.
|
||||
*
|
||||
|
||||
@@ -322,6 +322,59 @@ test("accepts experimental page status frontmatter", async () => {
|
||||
await assert.doesNotReject(validatePublicDocs(dir));
|
||||
});
|
||||
|
||||
test("rejects an experimental callout with no substantive section content", async () => {
|
||||
const dir = await createDocs(
|
||||
{
|
||||
"index.md": `${validPage}\n## Office dependencies\n\n> [!EXPERIMENTAL]\n> Office is disabled by default.\n`,
|
||||
},
|
||||
{ pages: ["index"] },
|
||||
);
|
||||
|
||||
await assert.rejects(
|
||||
validatePublicDocs(dir),
|
||||
/index.md has an experimental callout without substantive section content: Office dependencies/,
|
||||
);
|
||||
});
|
||||
|
||||
test("accepts a feature-specific experimental section with substantive content", async () => {
|
||||
const dir = await createDocs(
|
||||
{
|
||||
"index.md": `${validPage}\n## Office dependencies\n\n> [!EXPERIMENTAL]\n> Office is disabled by default.\n\nUse workflow approval steps for the supported human-gated path.\n`,
|
||||
},
|
||||
{ pages: ["index"] },
|
||||
);
|
||||
|
||||
await assert.doesNotReject(validatePublicDocs(dir));
|
||||
});
|
||||
|
||||
test("rejects an experimental callout dropped after unrelated section content", async () => {
|
||||
const dir = await createDocs(
|
||||
{
|
||||
"index.md": `${validPage}\n## Configure workflows\n\nRegular workflows support human review gates.\n\n> [!EXPERIMENTAL]\n> Office is disabled by default.\n\nUse workflow approval steps for stable human gates.\n`,
|
||||
},
|
||||
{ pages: ["index"] },
|
||||
);
|
||||
|
||||
await assert.rejects(
|
||||
validatePublicDocs(dir),
|
||||
/index.md experimental callouts must immediately follow a descriptive heading/,
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects an experimental callout not under a descriptive section heading", async () => {
|
||||
const dir = await createDocs(
|
||||
{
|
||||
"index.md": `${validPage}\n> [!EXPERIMENTAL]\n> Office is disabled by default.\n\nSome content.\n`,
|
||||
},
|
||||
{ pages: ["index"] },
|
||||
);
|
||||
|
||||
await assert.rejects(
|
||||
validatePublicDocs(dir),
|
||||
/index.md experimental callouts must immediately follow a descriptive heading/,
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects published pages without title and description frontmatter", async () => {
|
||||
const dir = await createDocs(
|
||||
{ "index.md": "# Kandev\n" },
|
||||
|
||||
Reference in New Issue
Block a user