feat(ep-td+dashboard): complete CUST-WP-0004 EP/TD tracking workstream
EP catalogue (all domains): - EP-RAIL-001 ep_id patched (schema fix: add ep_id to EPUpdate) - EP-RAIL-003 (git bare-repo mirrors) and EP-RAIL-004 (offsite secondary backup) registered from railiance-cluster/docs/backup-restore.md - EP-CUST-003..007 ep_ids assigned to existing custodian EPs - EP-CUST-008 (State Hub API auth) and EP-CUST-009 (update_workstream MCP tool) registered as new custodian extension points TD catalogue (railiance — first 5 items): - TD-RAIL-001: backup cron runs as root without audit trail (high/security) - TD-RAIL-002: k3s kubeconfig world-readable mode 644 (medium/security) - TD-RAIL-003: no Ansible role unit tests (medium/test) - TD-RAIL-004: age key extracted via awk — fragile (medium/impl) - TD-RAIL-005: etcd snapshot retention uncoordinated (low/impl) Dashboard (T08 + T10): - Extract API URL and POLL to src/components/config.js; all 15 pages now import from the shared module (contributions/goals keep custom POLL) - Shared .kpi-infobox, .filter-bar, .filter-search/.filter-owner CSS moved to observablehq.config.js head <style> block; removed from 9 pages - Build: 0 errors, 0 warnings API (T09): - progress.py: limit param now Query(100, le=1000) — prevents unbounded list requests; closes TD-CUST-004 for the only endpoint that had limit CUST-WP-0004 marked completed (all 10 tasks done). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter, Depends, status
|
||||
from fastapi import APIRouter, Depends, Query, status
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -19,7 +19,7 @@ async def list_progress(
|
||||
task_id: uuid.UUID | None = None,
|
||||
event_type: str | None = None,
|
||||
since: datetime | None = None,
|
||||
limit: int = 100,
|
||||
limit: int = Query(100, le=1000),
|
||||
session: AsyncSession = Depends(get_session),
|
||||
) -> list[ProgressEvent]:
|
||||
q = select(ProgressEvent)
|
||||
|
||||
@@ -69,6 +69,13 @@ export default {
|
||||
},
|
||||
],
|
||||
theme: ["air", "near-midnight"],
|
||||
head: `<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🗄️</text></svg>">`,
|
||||
head: `<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🗄️</text></svg>">
|
||||
<style>
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; padding-right: 1.6rem; }
|
||||
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
|
||||
.filter-search, .filter-owner { display: flex; align-items: center; }
|
||||
.filter-search input, .filter-owner input { height: 30px; font-size: 0.85rem; padding: 0.25rem 0.5rem; border-radius: 6px; border: 1px solid var(--theme-foreground-faint, #ccc); background: var(--theme-background, #fff); font-family: inherit; color: inherit; }
|
||||
</style>`,
|
||||
footer: "Custodian State Hub — local-first, append-only, sovereignty-preserving.",
|
||||
};
|
||||
|
||||
2
state-hub/dashboard/src/components/config.js
Normal file
2
state-hub/dashboard/src/components/config.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export const API = "http://127.0.0.1:8000";
|
||||
export const POLL = 15_000;
|
||||
@@ -3,7 +3,7 @@ title: Contributions
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
import {API} from "./components/config.js";
|
||||
const POLL = 30_000;
|
||||
```
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Decisions
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -392,25 +391,6 @@ if (escalated.length > 0) {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox {
|
||||
background: var(--theme-background-alt, #f9f9f9);
|
||||
border: 1px solid var(--theme-foreground-faint, #e0e0e0);
|
||||
border-radius: 10px;
|
||||
padding: 0.75rem 1rem;
|
||||
position: relative;
|
||||
box-shadow: 0 1px 6px rgba(0,0,0,0.07);
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.kpi-infobox-title {
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--theme-foreground-muted, #888);
|
||||
margin-bottom: 0.55rem;
|
||||
padding-right: 1.6rem; /* room for ? button */
|
||||
}
|
||||
.kpi-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -445,10 +425,6 @@ if (escalated.length > 0) {
|
||||
/* ── Utility ──────────────────────────────────────────────────────────────── */
|
||||
.dim { color: gray; font-style: italic; }
|
||||
|
||||
/* ── Filter bar ───────────────────────────────────────────────────────────── */
|
||||
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
|
||||
.filter-search { display: flex; align-items: center; }
|
||||
.filter-search input { height: 30px; font-size: 0.85rem; padding: 0.25rem 0.5rem; border-radius: 6px; border: 1px solid var(--theme-foreground-faint, #ccc); background: var(--theme-background, #fff); font-family: inherit; color: inherit; }
|
||||
|
||||
/* ── Decision list ────────────────────────────────────────────────────────── */
|
||||
.dec-list { display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Dependencies
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -136,8 +135,6 @@ if (edges.length === 0) {
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; }
|
||||
.kpi-row + .kpi-row { border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); white-space: nowrap; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Domains
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Extension Points
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -210,8 +209,6 @@ display(html`<div class="ep-list">${filtered.map(ep => html`
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row:first-of-type { border-top: none; }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); }
|
||||
@@ -225,7 +222,6 @@ display(html`<div class="ep-list">${filtered.map(ep => html`
|
||||
.chart-row { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start; }
|
||||
|
||||
/* ── Filters ──────────────────────────────────────────────────────────────── */
|
||||
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
|
||||
|
||||
/* ── EP list ──────────────────────────────────────────────────────────────── */
|
||||
.ep-list { display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Goals
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
import {API} from "./components/config.js";
|
||||
const POLL = 20_000;
|
||||
```
|
||||
|
||||
@@ -253,8 +253,6 @@ if (unlinkedRepoGoals.length > 0) {
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; }
|
||||
.kpi-row + .kpi-row { border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); white-space: nowrap; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Overview
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Interventions
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -193,8 +192,6 @@ if (closed.length === 0) {
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; }
|
||||
.kpi-row + .kpi-row { border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); white-space: nowrap; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Progress
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Repos
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
import {API} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
@@ -3,7 +3,7 @@ title: SBOM
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
import {API} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Tasks
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -235,8 +234,6 @@ display(buildEntityTable(
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; padding-right: 1.6rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; }
|
||||
.kpi-row + .kpi-row { border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); white-space: nowrap; }
|
||||
@@ -245,9 +242,6 @@ display(buildEntityTable(
|
||||
.kpi-row-sub { font-size: 0.68rem; color: var(--theme-foreground-faint, #aaa); line-height: 1.2; }
|
||||
|
||||
/* ── Filters ──────────────────────────────────────────────────────────────── */
|
||||
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
|
||||
.filter-owner { display: flex; align-items: center; }
|
||||
.filter-owner input { height: 30px; font-size: 0.85rem; padding: 0.25rem 0.5rem; border-radius: 6px; border: 1px solid var(--theme-foreground-faint, #ccc); background: var(--theme-background, #fff); font-family: inherit; color: inherit; }
|
||||
|
||||
/* ── Blocked task cards ───────────────────────────────────────────────────── */
|
||||
.task-blocked-list { display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Technical Debt
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -246,8 +245,6 @@ display(html`<div class="td-list">${filtered.map(t => html`
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row:first-of-type { border-top: none; }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); }
|
||||
@@ -259,7 +256,6 @@ display(html`<div class="td-list">${filtered.map(t => html`
|
||||
.chart-row { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start; }
|
||||
|
||||
/* ── Filters ──────────────────────────────────────────────────────────────── */
|
||||
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
|
||||
|
||||
/* ── TD list ──────────────────────────────────────────────────────────────── */
|
||||
.td-list { display: flex; flex-direction: column; gap: 0.5rem; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Todo
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
const THIS_REPO = "the-custodian";
|
||||
```
|
||||
|
||||
@@ -204,8 +203,6 @@ if (thirdParty.length === 0) {
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox ──────────────────────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; }
|
||||
.kpi-row + .kpi-row { border-top: 1px solid var(--theme-foreground-faint, #eee); }
|
||||
.kpi-row-label { font-size: 0.8rem; color: var(--theme-foreground-muted, #666); white-space: nowrap; }
|
||||
|
||||
@@ -3,8 +3,7 @@ title: Workstreams
|
||||
---
|
||||
|
||||
```js
|
||||
const API = "http://127.0.0.1:8000";
|
||||
const POLL = 15_000;
|
||||
import {API, POLL} from "./components/config.js";
|
||||
```
|
||||
|
||||
```js
|
||||
@@ -330,8 +329,6 @@ if (wsWithDeps.length === 0) {
|
||||
.live-indicator { font-size: 0.8rem; color: gray; position: relative; padding: 0.55rem 1.8rem 0.55rem 0.7rem; margin-bottom: 0.75rem; }
|
||||
|
||||
/* ── KPI infobox base (shared) ───────────────────────────────────────────── */
|
||||
.kpi-infobox { background: var(--theme-background-alt, #f9f9f9); border: 1px solid var(--theme-foreground-faint, #e0e0e0); border-radius: 10px; padding: 0.75rem 1rem; position: relative; box-shadow: 0 1px 6px rgba(0,0,0,0.07); margin-bottom: 1.25rem; }
|
||||
.kpi-infobox-title { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--theme-foreground-muted, #888); margin-bottom: 0.55rem; padding-right: 1.6rem; }
|
||||
.kpi-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 0.3rem 0; }
|
||||
.kpi-muted { color: var(--theme-foreground-faint, #aaa); font-style: italic; font-size: 0.8rem; }
|
||||
|
||||
@@ -352,9 +349,6 @@ if (wsWithDeps.length === 0) {
|
||||
.whi-domain-name { flex: 1; font-size: 0.75rem; color: var(--theme-foreground-muted, #666); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.whi-domain-score { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 0.75rem; }
|
||||
.dim { color: gray; font-style: italic; }
|
||||
.filter-bar { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 1rem; }
|
||||
.filter-owner { display: flex; align-items: center; }
|
||||
.filter-owner input { height: 30px; font-size: 0.85rem; padding: 0.25rem 0.5rem; border-radius: 6px; border: 1px solid var(--theme-foreground-faint, #ccc); background: var(--theme-background, #fff); font-family: inherit; color: inherit; }
|
||||
.dep-grid { display: flex; flex-direction: column; gap: 0.75rem; }
|
||||
.dep-card { border: 1px solid #e0e0e0; border-radius: 6px; padding: 0.75rem 1rem; background: var(--theme-background-alt, #fafafa); }
|
||||
.dep-title { font-weight: 600; margin-bottom: 0.25rem; }
|
||||
|
||||
@@ -3,12 +3,13 @@ id: CUST-WP-0004
|
||||
type: workplan
|
||||
title: "Extension Points & Technical Debt Tracking"
|
||||
domain: custodian
|
||||
status: active
|
||||
status: completed
|
||||
owner: custodian
|
||||
topic_slug: custodian
|
||||
state_hub_workstream_id: e84ecd70-b276-4a93-a298-1ef1299b7c22
|
||||
created: "2026-02-27"
|
||||
updated: "2026-02-28"
|
||||
updated: "2026-03-11"
|
||||
completed: "2026-03-11"
|
||||
---
|
||||
|
||||
# Extension Points & Technical Debt Tracking
|
||||
@@ -87,7 +88,7 @@ endpoints).
|
||||
```task
|
||||
id: CUST-WP-0004-T05
|
||||
state_hub_task_id: 00492d87-3bb7-4df9-8f12-a06da0307fbc
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
@@ -99,7 +100,7 @@ Register findings as `TD-RAIL-xxx` items via the `/technical-debt/` API.
|
||||
```task
|
||||
id: CUST-WP-0004-T06
|
||||
state_hub_task_id: 3069aa1d-3d5f-4b9f-be8b-dfa0ffe690fe
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
@@ -112,7 +113,7 @@ gaps, integration opportunities.
|
||||
```task
|
||||
id: CUST-WP-0004-T07
|
||||
state_hub_task_id: 3a355a74-237f-4572-af05-683eceb32694
|
||||
status: todo
|
||||
status: done
|
||||
priority: low
|
||||
```
|
||||
|
||||
@@ -123,7 +124,7 @@ Identify and register extension points in railiance as `EP-RAIL-xxx` items.
|
||||
```task
|
||||
id: CUST-WP-0004-T08
|
||||
state_hub_task_id: a9b5d39e-706b-4f71-8f5d-ce4f927b3e4c
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
@@ -136,7 +137,7 @@ variable.
|
||||
```task
|
||||
id: CUST-WP-0004-T09
|
||||
state_hub_task_id: 7050eb96-964d-4c06-a9f5-6d49db6b9c98
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
@@ -149,7 +150,7 @@ technical_debt) to prevent memory exhaustion.
|
||||
```task
|
||||
id: CUST-WP-0004-T10
|
||||
state_hub_task_id: c54553be-d947-4b8d-9c16-eb1a0e9ae3a0
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user