diff --git a/pages/dashboard/PLAN.md b/pages/dashboard/PLAN.md index 9ad6cda..14b9dae 100644 --- a/pages/dashboard/PLAN.md +++ b/pages/dashboard/PLAN.md @@ -18,6 +18,7 @@ - [x] Slice: `DLS-PAGE-003` through `DLS-PAGE-013` conservative required-field coverage validation for built-in page definitions. - [x] Slice: `DLS-PAGE-014` conservative built-in data-state exposure validation via implementation-local declarative markers. - [x] Slice: `DLS-PAGE-006` conservative run-link coverage validation for the `runs` built-in page. + - [x] Slice: `DLS-PAGE-002` conservative `overview` linked-findings and operational-value timeline coverage validation. - [ ] **Security, privacy, accessibility** — Section 13 including escaping, redaction, and keyboard and screen-reader behavior verified with Playwright. - [ ] **Compliance suite** — Section 14 test suite, the compliance checklist, Appendix A as a passing fixture, and Appendix C as failing fixtures. - [ ] **Parity** — inventory the features of the existing dashboard in `.github/scripts/pages-report/report.mjs`, record them in `PLAN.md` as a parity checklist, then express each one as YAML configuration plus data fixtures, closing the checklist incrementally. @@ -37,6 +38,14 @@ ## Run log +### 2026-08-29 (built-in overview linked-findings and operational-value timeline slice) + +- Extended the Built-in pages milestone with a narrow `DLS-PAGE-002` validator increment for conservative `overview` coverage of recent linked findings and operational-value timelines. +- Updated `src/specification.js` so the implementation-local declarative definition for the `overview` built-in page now requires relation-specific finding links (`issue-link`, `pull-request-link`, `run-link`) plus `operational-value-definition` alongside `operational-value` and `observed-at`. +- Expanded `test/unit/validator.test.js` with a negative `overview` built-in fixture that now fails when linked finding fields or definition-aware operational-value timeline coverage are omitted, and updated the positive built-in coverage fixture to include an `overview` page satisfying those requirements. +- Verified `npm install`, `npm run typecheck`, `npm run lint`, and `npm test`; `npm run test:e2e` remains blocked in this environment because the Playwright Chromium executable is not provisioned (`browserType.launch: Executable doesn't exist`). +- Next milestone: Built-in pages, next slice for conservative validation of `overview` provenance and freshness exposure obligations without inventing presenter semantics. + ### 2026-08-29 (built-in runs run-link coverage slice) - Extended the Built-in pages milestone with a narrow `DLS-PAGE-006` validator increment for conservative run-link coverage on the `runs` built-in page. diff --git a/pages/dashboard/README.md b/pages/dashboard/README.md index b9342de..b46b1db 100644 --- a/pages/dashboard/README.md +++ b/pages/dashboard/README.md @@ -27,3 +27,5 @@ The latest provenance/freshness/data-states slice audited Section 8 and recorded The current built-in-pages slice adds a conservative implementation-local built-in `definition.views` shape so Section 10 pages can declare custom-view-style source and field coverage without inventing presenter behavior beyond the specification's built-in page names and required-source catalog. The latest built-in-pages increment also adds a conservative implementation-local `definition.data-state` marker for `DLS-PAGE-014`, requiring declarative independent coverage of `availability`, `completeness`, and `freshness` on built-in pages. + +The current built-in-pages slice extends conservative Section 10 coverage for `overview`, requiring declarative built-in definitions to expose recent linked findings through relation-specific finding links and to expose operational-value timelines with definition-aware series coverage. diff --git a/pages/dashboard/src/specification.js b/pages/dashboard/src/specification.js index 2d6cdb6..677098b 100644 --- a/pages/dashboard/src/specification.js +++ b/pages/dashboard/src/specification.js @@ -122,8 +122,8 @@ export const BUILT_IN_PAGE_REQUIRED_FIELDS = { workflows: ['workflow-active', 'rollout-mode'], runs: ['run-status', 'run-conclusion', 'repository', 'workflow'], usage: ['aic'], - findings: ['observed-at'], - 'operational-values': ['operational-value', 'observed-at'] + findings: ['observed-at', 'issue-link', 'pull-request-link', 'run-link'], + 'operational-values': ['operational-value', 'operational-value-definition', 'observed-at'] }, organizations: { organizations: ['organization'], diff --git a/pages/dashboard/test/unit/validator.test.js b/pages/dashboard/test/unit/validator.test.js index 2310d98..bcee770 100644 --- a/pages/dashboard/test/unit/validator.test.js +++ b/pages/dashboard/test/unit/validator.test.js @@ -556,6 +556,94 @@ dashboard: } }); + it('DLS-PAGE-002 DLS-PAGE-014 rejects an overview built-in page definition that omits linked findings and operational-value timeline coverage with DLS-E003', () => { + const result = validateDashboardDocument(`language-version: "0.1.0" +dashboard: + id: incomplete-overview-page + title: Incomplete Overview Page + pages: + - id: overview + kind: built-in + page: overview + title: Overview + definition: + data-state: + availability: true + completeness: true + freshness: true + views: + - id: workflows-view + data: + source: workflows + mark: table + encoding: + columns: + - field: workflow-active + - field: rollout-mode + - id: runs-view + data: + source: runs + mark: table + encoding: + columns: + - field: run-status + - field: run-conclusion + - field: repository + - field: workflow + - id: usage-view + data: + source: usage + mark: metric + encoding: + value: + field: aic + aggregate: sum + - id: findings-view + data: + source: findings + mark: table + encoding: + columns: + - field: observed-at + - id: operational-values-view + data: + source: operational-values + mark: table + encoding: + columns: + - field: operational-value + - field: observed-at +`); + + expect(result.ok).toBe(false); + if (!result.ok) { + expect(result.errors).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + code: 'DLS-E003', + path: '$.dashboard.pages[0].definition.views', + message: 'built-in page "overview" definition must expose field "issue-link" for source "findings".' + }), + expect.objectContaining({ + code: 'DLS-E003', + path: '$.dashboard.pages[0].definition.views', + message: 'built-in page "overview" definition must expose field "pull-request-link" for source "findings".' + }), + expect.objectContaining({ + code: 'DLS-E003', + path: '$.dashboard.pages[0].definition.views', + message: 'built-in page "overview" definition must expose field "run-link" for source "findings".' + }), + expect.objectContaining({ + code: 'DLS-E003', + path: '$.dashboard.pages[0].definition.views', + message: 'built-in page "overview" definition must expose field "operational-value-definition" for source "operational-values".' + }) + ]) + ); + } + }); + it('DLS-PAGE-014 rejects a built-in page definition that does not expose independent availability, completeness, and freshness', () => { const result = validateDashboardDocument(`language-version: "0.1.0" dashboard: @@ -668,12 +756,86 @@ dashboard: } }); - it('DLS-PAGE-006 DLS-PAGE-010 DLS-PAGE-011 DLS-PAGE-012 DLS-PAGE-013 DLS-PAGE-014 accepts built-in definitions that conservatively cover required fields', () => { + it('DLS-PAGE-002 DLS-PAGE-006 DLS-PAGE-010 DLS-PAGE-011 DLS-PAGE-012 DLS-PAGE-013 DLS-PAGE-014 accepts built-in definitions that conservatively cover required fields', () => { const result = validateDashboardDocument(`language-version: "0.1.0" dashboard: id: built-in-field-coverage title: Built In Field Coverage pages: + - id: overview + kind: built-in + page: overview + title: Overview + definition: + data-state: + availability: true + completeness: true + freshness: true + views: + - id: workflow-inventory + data: + source: workflows + mark: table + encoding: + columns: + - field: workflow-active + - field: rollout-mode + - id: run-trends + data: + source: runs + mark: chart + encoding: + x: + field: started-at + type: temporal + time-unit: day + y: + field: run + aggregate: count + color: + field: run-conclusion + - id: run-rankings + data: + source: runs + mark: table + encoding: + columns: + - field: repository + - field: workflow + - field: run-status + - field: run-conclusion + - id: usage-metric + data: + source: usage + mark: metric + encoding: + value: + field: aic + aggregate: sum + - id: recent-findings + data: + source: findings + mark: table + encoding: + columns: + - field: observed-at + - field: issue-link + - field: pull-request-link + - field: run-link + - id: operational-value-timeline + data: + source: operational-values + mark: chart + encoding: + x: + field: observed-at + type: temporal + time-unit: day + y: + field: operational-value + aggregate: max + color: + field: operational-value-definition - id: runs kind: built-in page: runs