docs(policy): add Repository Definition of Integrated (DoI)
Three-tier checklist defining what 'fully integrated with the state-hub' means for a repository: - Core (Registered): registered, domain assigned, path resolves, remote URL - Standard (Integrated): SCOPE.md, CLAUDE.md, workplan convention, SBOM, TPSC - Full (Fully Integrated): repo goal, capabilities declared, agents template, clean consistency check, host paths registered Exposed via /policy/repo-doi (editable in dashboard) and linked under Policies. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ export default {
|
||||
collapsible: true,
|
||||
open: false,
|
||||
pages: [
|
||||
{ name: "Repository DoI", path: "/policy/repo-doi" },
|
||||
{ name: "Workstream DoD", path: "/policy/workstream-dod" },
|
||||
],
|
||||
},
|
||||
|
||||
90
state-hub/dashboard/src/policy/repo-doi.md
Normal file
90
state-hub/dashboard/src/policy/repo-doi.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Repository Definition of Integrated (DoI)
|
||||
---
|
||||
|
||||
```js
|
||||
import {API} from "../components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
import {marked} from "npm:marked";
|
||||
|
||||
const _resp = await fetch(`${API}/policy/repo-doi`);
|
||||
if (!_resp.ok) throw new Error(`Failed to load policy: ${_resp.status}`);
|
||||
const _policy = await _resp.json();
|
||||
```
|
||||
|
||||
```js
|
||||
let _content = _policy.content;
|
||||
let _editing = false;
|
||||
|
||||
const _root = display(html`<div></div>`);
|
||||
|
||||
async function _save(text) {
|
||||
const r = await fetch(`${API}/policy/repo-doi`, {
|
||||
method: "PUT",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({content: text}),
|
||||
});
|
||||
if (!r.ok) throw new Error(`Save failed: ${r.status}`);
|
||||
_content = text;
|
||||
}
|
||||
|
||||
function _toolbar(...nodes) {
|
||||
return html`<div style="display:flex;gap:0.5rem;margin-bottom:1rem">${nodes}</div>`;
|
||||
}
|
||||
|
||||
function _btn(label, primary = false) {
|
||||
return html`<button style="
|
||||
padding:0.35rem 0.9rem;border-radius:4px;cursor:pointer;font-size:13px;
|
||||
background:${primary ? "#1e293b" : "#f1f5f9"};
|
||||
color:${primary ? "#f8fafc" : "#1e293b"};
|
||||
border:1px solid ${primary ? "#1e293b" : "#cbd5e1"};
|
||||
">${label}</button>`;
|
||||
}
|
||||
|
||||
function _render() {
|
||||
_root.innerHTML = "";
|
||||
|
||||
if (_editing) {
|
||||
const area = html`<textarea style="
|
||||
width:100%;box-sizing:border-box;height:520px;
|
||||
font-family:ui-monospace,monospace;font-size:13px;line-height:1.6;
|
||||
padding:0.75rem;border:1px solid #cbd5e1;border-radius:4px;
|
||||
background:#f8fafc;color:#1e293b;resize:vertical;
|
||||
">${_content}</textarea>`;
|
||||
|
||||
const saveBtn = _btn("Save", true);
|
||||
const cancelBtn = _btn("Cancel");
|
||||
|
||||
saveBtn.onclick = async () => {
|
||||
saveBtn.disabled = true;
|
||||
saveBtn.textContent = "Saving…";
|
||||
try {
|
||||
await _save(area.value);
|
||||
_editing = false;
|
||||
_render();
|
||||
} catch (e) {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.textContent = "Save";
|
||||
alert(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
cancelBtn.onclick = () => { _editing = false; _render(); };
|
||||
|
||||
_root.append(_toolbar(saveBtn, cancelBtn), area);
|
||||
|
||||
} else {
|
||||
const editBtn = _btn("Edit");
|
||||
editBtn.onclick = () => { _editing = true; _render(); };
|
||||
|
||||
const body = html`<div style="max-width:720px;line-height:1.7;"></div>`;
|
||||
body.innerHTML = marked.parse(_content);
|
||||
|
||||
_root.append(_toolbar(editBtn), body);
|
||||
}
|
||||
}
|
||||
|
||||
_render();
|
||||
```
|
||||
120
state-hub/policies/repo-doi.md
Normal file
120
state-hub/policies/repo-doi.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Repository Definition of Integrated (DoI)
|
||||
|
||||
A repository is considered **fully integrated** with the Custodian State Hub
|
||||
when all criteria below are satisfied. Criteria are grouped by tier: a repo
|
||||
that meets all **Core** criteria is *registered*; meeting **Standard** criteria
|
||||
makes it *integrated*; meeting **Full** criteria makes it *fully integrated*.
|
||||
|
||||
---
|
||||
|
||||
## Tier 1 — Core (Registered)
|
||||
|
||||
These are the minimum requirements for the state-hub to be aware of a repo.
|
||||
|
||||
- [ ] **Registered in state-hub** — repo exists in `managed_repos` with correct
|
||||
`slug`, `domain_slug`, `local_path`, and `remote_url`. Verify:
|
||||
`GET /repos/{slug}`
|
||||
|
||||
- [ ] **Domain assigned** — repo is linked to an active domain. The domain must
|
||||
exist in `domains` and be in `active` status.
|
||||
|
||||
- [ ] **Local path resolves** — `_resolve_repo_path()` finds an existing
|
||||
directory on the current host (either via `host_paths[hostname]` or
|
||||
`local_path`, both support `~` expansion).
|
||||
|
||||
- [ ] **Remote URL reachable** — `remote_url` points to a live Gitea/GitHub
|
||||
repository. The repo must be pushable from the registered local path.
|
||||
|
||||
---
|
||||
|
||||
## Tier 2 — Standard (Integrated)
|
||||
|
||||
A repo at this tier participates in state-hub tracking and tooling.
|
||||
|
||||
- [ ] **SCOPE.md present** — a `SCOPE.md` exists at the repo root following the
|
||||
standard template (`state-hub/scripts/project_rules/scope.template`).
|
||||
Sections: One-liner, Core Idea, In Scope, Out of Scope, Relevant When,
|
||||
Not Relevant When, Current State, How It Fits, Provided Capabilities.
|
||||
|
||||
- [ ] **CLAUDE.md present** — a `CLAUDE.md` exists at the repo root with at
|
||||
minimum: domain context, session protocol (start: `get_domain_summary`,
|
||||
end: `add_progress_event`), and stack/commands reference.
|
||||
|
||||
- [ ] **Workplan convention followed** — any workplans live under
|
||||
`workplans/<ID>-<slug>.md` with valid YAML frontmatter
|
||||
(`id`, `type`, `title`, `domain`, `status`, `state_hub_workstream_id`).
|
||||
Verified by: `make check-consistency REPO={slug}` → PASS or WARN only
|
||||
(no FAIL).
|
||||
|
||||
- [ ] **SBOM ingested** — at least one dependency lockfile exists
|
||||
(`uv.lock`, `requirements.txt`, `package-lock.json`, `yarn.lock`,
|
||||
`Cargo.lock`, `go.sum`) and has been ingested:
|
||||
`make ingest-sbom REPO={slug}` succeeded with ≥1 entry.
|
||||
`last_sbom_at` is set on the repo record.
|
||||
|
||||
- [ ] **TPSC declared** — a `tpsc.yaml` exists at the repo root declaring all
|
||||
external service dependencies, and has been ingested:
|
||||
`make ingest-tpsc REPO={slug}` succeeded. If the repo has no external
|
||||
service dependencies, `tpsc.yaml` must exist with an empty `services: []`
|
||||
to make the absence explicit.
|
||||
|
||||
---
|
||||
|
||||
## Tier 3 — Full (Fully Integrated)
|
||||
|
||||
A fully integrated repo contributes to cross-repo planning and capability routing.
|
||||
|
||||
- [ ] **Active repo goal** — at least one `RepoGoal` with `status: active`
|
||||
exists for the repo in the state-hub. Goals connect workstreams to
|
||||
strategic intent. Create via: `create_repo_goal(repo_slug, title, ...)`
|
||||
|
||||
- [ ] **Provided Capabilities declared** — if the repo exposes capabilities to
|
||||
other domains, they are declared in the `## Provided Capabilities` section
|
||||
of `SCOPE.md` using `capability` fenced blocks and have been ingested via
|
||||
`make ingest-capabilities REPO={slug}`.
|
||||
|
||||
- [ ] **Agents template applied** — `CLAUDE.md` references the kaizen agent
|
||||
system (`get_kaizen_agent()`) and includes the `agents.template` section
|
||||
listing available specialised personas for the domain.
|
||||
|
||||
- [ ] **Consistency check clean** — `make check-consistency REPO={slug}`
|
||||
reports **0 FAIL, 0 WARN** (C-12 warnings on legacy DB-only tasks are
|
||||
exempt if the workstream predates ADR-001).
|
||||
|
||||
- [ ] **Host path registered for all active hosts** — `host_paths` contains
|
||||
an entry for every machine where the repo is actively worked on. Use
|
||||
`update_repo_path(slug, path)` to register additional hosts.
|
||||
|
||||
---
|
||||
|
||||
## Integration Checklist (Quick Reference)
|
||||
|
||||
| # | Criterion | Tier | Verified by |
|
||||
|---|---|---|---|
|
||||
| 1 | Registered in state-hub | Core | `GET /repos/{slug}` |
|
||||
| 2 | Domain assigned | Core | `GET /repos/{slug}` → `domain_slug` |
|
||||
| 3 | Local path resolves | Core | `check_repo_consistency(slug)` |
|
||||
| 4 | Remote URL reachable | Core | `git push` dry-run |
|
||||
| 5 | SCOPE.md present | Standard | `ls SCOPE.md` |
|
||||
| 6 | CLAUDE.md present | Standard | `ls CLAUDE.md` |
|
||||
| 7 | Workplan convention followed | Standard | `make check-consistency` |
|
||||
| 8 | SBOM ingested | Standard | `last_sbom_at` on repo record |
|
||||
| 9 | TPSC declared | Standard | `make ingest-tpsc` |
|
||||
| 10 | Active repo goal | Full | `get_repo_goals(slug)` |
|
||||
| 11 | Provided Capabilities declared | Full | `make ingest-capabilities` |
|
||||
| 12 | Agents template applied | Full | `CLAUDE.md` review |
|
||||
| 13 | Consistency check clean | Full | `make check-consistency` → 0 FAIL/WARN |
|
||||
| 14 | Host paths registered | Full | `GET /repos/{slug}` → `host_paths` |
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- The DoI is enforced by convention, not by automated gates (as of v0.6).
|
||||
A future `make check-doi REPO={slug}` target is planned.
|
||||
- Repos that are `archived` or `deprecated` are exempt from DoI compliance.
|
||||
- The **Core** tier is a prerequisite for all state-hub tooling
|
||||
(`check_repo_consistency`, `ingest_sbom_tool`, `ingest_tpsc_tool`).
|
||||
- A repo may satisfy **Standard** without **Full** indefinitely — Full
|
||||
integration is appropriate when the repo is actively contributing to
|
||||
cross-domain work or exposing capabilities to other repos.
|
||||
Reference in New Issue
Block a user