Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/node-status.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Node-status acceptance. This job is not a required check and is not part of
# workspace-landing. It does not edit any existing workflow step.
name: Node status

on:
pull_request:
paths:
- 'architecture/node-status.schema.json'
- 'records/node_status/**'
- 'docs/site/**'
- 'tools/validate_node_status.py'
- 'tools/current_site_history.py'
- 'tests/test_node_status_atlas.mjs'
- 'tests/fixtures/node_status/**'
- '.github/workflows/node-status.yml'
push:
branches: [main]
paths:
- 'architecture/node-status.schema.json'
- 'records/node_status/**'
- 'docs/site/**'
- 'tools/validate_node_status.py'
- 'tools/current_site_history.py'
- 'tests/test_node_status_atlas.mjs'
- 'tests/fixtures/node_status/**'
- '.github/workflows/node-status.yml'

permissions:
contents: read

jobs:
node-status:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- name: Node-status atlas test and validator
run: |
node --test tests/test_node_status_atlas.mjs
python3 -B -S tools/validate_node_status.py records/node_status
149 changes: 149 additions & 0 deletions architecture/node-status.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "architecture/node-status.schema.json",
"title": "Node status record v0",
"description": "Current view of one graph node. status is freshness of this view only, never scientific validity. scientific_effect stays NONE. owner is null or an object; released_url, when present, stays on that object and does not clear it. source_rev equals sources[0].rev, one value, never comma-joined. Receipts are referenced by sources[].url and sources[].rev and are not copied. predecessor, successor, carried_forward, and refresh_error are optional.",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"node_id",
"owner",
"next_action",
"missing_input",
"stops",
"sources",
"source_rev",
"observed_at",
"status",
"scientific_effect"
],
"properties": {
"schema_version": {"const": 0},
"node_id": {
"type": "string",
"minLength": 1,
"pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]*$"
},
"owner": {
"oneOf": [
{"type": "null"},
{
"type": "object",
"additionalProperties": false,
"required": ["id", "evidence_url"],
"properties": {
"id": {"type": "string", "minLength": 1},
"evidence_url": {
"type": "string",
"pattern": "^https://github\\.com/d6g8k5htny-coder/(main|Math-)/(issues|pull)/[1-9]\\d*#(issuecomment-[1-9]\\d*|pullrequestreview-[1-9]\\d*)$"
},
"released_url": {
"type": "string",
"pattern": "^https://github\\.com/d6g8k5htny-coder/(main|Math-)/(issues|pull)/[1-9]\\d*#(issuecomment-[1-9]\\d*|pullrequestreview-[1-9]\\d*)$"
}
}
}
]
},
"next_action": {"type": "string", "minLength": 1},
"missing_input": {
"type": "array",
"items": {"type": "string", "minLength": 1}
},
"stops": {
"type": "array",
"items": {"type": "string", "minLength": 1}
},
"sources": {
"type": "array",
"minItems": 1,
"items": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": ["url", "rev"],
"properties": {
"url": {
"type": "string",
"pattern": "^https://github\\.com/d6g8k5htny-coder/(main|Math-)/(blob|tree)/[0-9a-f]{40}/[A-Za-z0-9_./-]+$"
},
"rev": {"type": "string", "pattern": "^[0-9a-f]{40}$"}
}
},
{
"type": "object",
"additionalProperties": false,
"required": ["url", "rev"],
"properties": {
"url": {
"type": "string",
"pattern": "^https://github\\.com/d6g8k5htny-coder/(main|Math-)/(issues|pull)/[1-9]\\d*(#(issuecomment-[1-9]\\d*|pullrequestreview-[1-9]\\d*))?$"
},
"rev": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}
}
}
]
}
},
"source_rev": {
"type": "string",
"pattern": "^(?:[0-9a-f]{40}|\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z)$"
},
"observed_at": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"
},
"status": {"enum": ["fresh", "stale", "unknown"]},
"scientific_effect": {"const": "NONE"},
"predecessor": {
"oneOf": [
{"type": "null"},
{
"type": "object",
"additionalProperties": false,
"required": ["node_id", "url"],
"properties": {
"node_id": {"type": "string", "minLength": 1},
"url": {"type": "string", "pattern": "^https?://\\S+$"}
}
}
]
},
"successor": {
"oneOf": [
{"type": "null"},
{
"type": "object",
"additionalProperties": false,
"required": ["node_id", "url"],
"properties": {
"node_id": {"type": "string", "minLength": 1},
"url": {"type": "string", "pattern": "^https?://\\S+$"}
}
}
]
},
"carried_forward": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["id", "text", "source_url", "status"],
"properties": {
"id": {"type": "string", "minLength": 1},
"text": {"type": "string", "minLength": 1},
"source_url": {"type": "string", "minLength": 1},
"status": {"enum": ["open", "resolved"]},
"resolution_url": {
"type": "string",
"minLength": 1,
"pattern": "^https://github\\.com/d6g8k5htny-coder/(main|Math-)/(issues|pull)/[1-9]\\d*#(issuecomment-[1-9]\\d*|pullrequestreview-[1-9]\\d*)$"
}
}
}
},
"refresh_error": {"type": ["string", "null"]}
}
}
2 changes: 1 addition & 1 deletion docs/site/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The front and technical layers use the same existing evidence. No second scienti

`tools/current_site_data.py` resolves public main and Math- commits once, verifies their complete Git trees and the seven acquired source files, and extracts exact indented proof displays. Other inventory rows bind paths and Git blobs; their document bytes are not downloaded. The page calls equation blocks excerpts and keeps their surrounding proof scope available by pinned line links. `tools/current_site_build.py` renders one payload offline into marked current sections and static node pages; Research and Formal stay script-free. Current observations and original dated reading cuts have separate identities.

"Resume this node" appears in the atlas inspector and on each current static node page. Both come from `resumeProjection` in `current-model.mjs`; `tools/current_site_history.py` keeps a Python copy, and `tests/test_current_site_resume.mjs` checks that the two agree on every node. The block names the snapshot's graph commit, path, SHA-256 and observation time, and warns readers to refresh from the live record before any ownership- or head-dependent action. Recorded `review_*` fields are labelled as review records, not as the current task, an owner or completion. Next action, missing input, owner evidence and retained stop read "not recorded in this snapshot", because the graph records none of them. A bare `review_issue` number names no repository, so it is not linked. Continuation links come only from the small site-maintained `RESUME_TASK_RECORDS` table of explicitly identified operational pointers; they are not graph metadata, scientific acceptance or source-binding admission. Archived snapshot pages are unchanged.
"Resume this node" appears in the atlas inspector and on each current static node page. Both come from `resumeProjection` in `current-model.mjs`; `tools/current_site_history.py` keeps a Python copy, and `tests/test_current_site_resume.mjs` checks that the two agree on every node. The block names the snapshot's graph commit, path, SHA-256 and observation time, and warns readers to refresh from the live record before any ownership- or head-dependent action. Recorded `review_*` fields are labelled as review records, not as the current task, an owner or completion. Next action, missing input, owner evidence and retained stop read "not recorded in this snapshot" on the snapshot-only projection, because the graph records none of them. The atlas inspector also passes `node-status.json`, the published copy of `records/node_status`, into that same projection. Static node pages stay on the snapshot-only call. An owner object is shown only when `evidence_url` matches the shared comment pattern; `released_url`, when present, stays on that object and the atlas says released. The panel shows the recorded status and `observed_at`, and says stale when `observed_at` is more than 24 hours before the render clock. Status is freshness of that view, not scientific validity, and `scientific_effect` stays NONE. A bare `review_issue` number names no repository, so it is not linked. Continuation links come only from the small site-maintained `RESUME_TASK_RECORDS` table of explicitly identified operational pointers; they are not graph metadata, scientific acceptance or source-binding admission. Archived snapshot pages are unchanged.

The configured `.github/workflows/current-site.yml` builds on main pushes and a 30-minute schedule and deploys the complete tested docs artifact through Pages Actions. Each candidate needs its own hosted success and deployed-source acceptance. A failed source refresh cannot reach deployment. Source observations are not mathematical revalidation. Existing diagrams on Explore keep their defined teaching scope; the new source panel links the advancing work.

Expand Down
11 changes: 7 additions & 4 deletions docs/site/atlas.mjs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import {currentSnapshot,element,anchor} from './current.mjs?site-release=8a66eb0ad9971fbffe07579998488e81195a024161995c3c4c7d4b34e1ec7262';
import {hasNode,readState,neighborhood,searchGraph,downstreamReach,requiredDependencyPaths,REQUIRED_ROUTE_SEMANTICS,evidenceAxes,sourceURL,sourceForNode,nodePage,resumeProjection,RESUME_NOT_RECORDED} from './current-model.mjs?site-release=713e81d352fe16f86116e405448ab16604f861c360841ba0f7d7396fd9ccb594';
import {currentSnapshot,element,anchor} from './current.mjs?site-release=c678bd088183b6548c4b094e8f7db287c9ab07f1ad2064737dc6eee9b82332d8';
import {hasNode,readState,neighborhood,searchGraph,downstreamReach,requiredDependencyPaths,REQUIRED_ROUTE_SEMANTICS,evidenceAxes,sourceURL,sourceForNode,nodePage,resumeProjection,RESUME_NOT_RECORDED,resumeFieldHref} from './current-model.mjs?site-release=e2a859394fa5607936ba766a76875392cf43b7c424f0c52542b68a539dcdc1dd';
import {createAtlasShell,viewForViewport} from './atlas-shell.mjs?site-release=9fce5f707e3486ef152ffdaa1cf1e4adf7cd9cf9dac116407a69b6528b4c656c';
const byId=id=>document.getElementById(id);
const svgElement=(tag,attrs)=>{const n=document.createElementNS('http://www.w3.org/2000/svg',tag);for(const [k,v]of Object.entries(attrs))n.setAttribute(k,String(v));return n;};
// Mirrors the static node page block rendered from the same projection by tools/current_site_history.py.
function resumeSection(view){const section=element('section',undefined,'resume-node');section.id='atlas-resume';section.setAttribute('aria-labelledby','atlas-resume-heading');const heading=element('h4','Resume this node');heading.id='atlas-resume-heading';
const fields=items=>{const dl=element('dl',undefined,'resume-fields');for(const item of items){const dd=element('dd');if(item.url)dd.append(anchor(item.text,item.url));else dd.append(element('code',item.text));if(item.note)dd.append(` ${item.note}`);dl.append(element('dt',item.label||item.field),dd);}return dl;};
const fields=items=>{const dl=element('dl',undefined,'resume-fields');for(const item of items){const dd=element('dd');const href=resumeFieldHref(item);if(href)dd.append(anchor(item.text,href));else dd.append(element('code',item.text));if(item.note)dd.append(` ${item.note}`);dl.append(element('dt',item.label||item.field),dd);}return dl;};
const s=view.snapshot,warning=element('p',undefined,'resume-warning');warning.dataset.freshness=view.freshness;warning.append(element('strong',`As of ${s.observed_at} · ${view.freshness}.`),` ${view.warning}${view.freshness==='current'?'':' Do not rely on this snapshot for current ownership or heads.'}`);
section.append(heading,warning,element('p',`Snapshot identity: graph ${s.graph_repository} commit ${s.graph_commit} · ${s.graph_path} · SHA-256 ${s.graph_sha256} · main commit ${s.main_commit||RESUME_NOT_RECORDED}.`),element('h5','Recorded graph state'),fields(view.state),element('h5','Recorded review record'),element('p',view.review.label),view.review.fields.length?fields(view.review.fields):element('p',`Review metadata: ${RESUME_NOT_RECORDED}.`),element('h5','Operational task state'),fields(view.operational),element('h5','Continuation'));
const task=view.continuation,p=element('p');if(task)p.append(anchor(task.label,task.url),`. ${task.meaning} Site-maintained pointer, not part of the graph snapshot; identified on ${task.identified_on} in `,anchor("the coordinator's activation record",task.identified_in),'. The linked comment is mutable; read it live before acting.');else p.textContent=view.continuation_text;section.append(p);return section;}
// Published copy of records/node_status. A missing file leaves the snapshot-only projection.
async function loadNodeStatus(){try{const response=await fetch('node-status.json',{cache:'no-store',credentials:'omit'});if(!response.ok)return null;const body=await response.json();return body&&typeof body==='object'&&!Array.isArray(body)?body:null;}catch{return null;}}
function linkRecord(label,value){const p=element('p');if(typeof value==='string'){try{const u=new URL(value);if(u.protocol==='https:'&&u.hostname==='github.com'&&!u.username&&!u.password&&!u.port){p.append(anchor(label,value));return p;}}catch{}}p.textContent=`${label}: ${value||'not recorded'}`;return p;}
async function start() {
const nodeStatus=await loadNodeStatus();
const root=byId('current-atlas');if(!root)return;
const data=await currentSnapshot;
if(!data){byId('atlas-status').textContent='Unavailable: current snapshot did not verify. Use the static source index and preserved snapshot below.';return;}
Expand All @@ -37,7 +40,7 @@ async function start() {
const reachPanel=element('p',reachText);reachPanel.id='atlas-reach';panel.append(reachPanel,element('p',`Complete indexed snapshot query at ${data.graph.identity.commit}. Each count excludes the selected node and counts distinct downstream nodes. All edges includes context; required edges uses required edges at every step. These counts do not identify blocked theorems or prove completeness.`));byId('atlas-diagnostic-selection').textContent=`Selected ${selected}: ${reachText} No scientific disposition is inferred.`;
panel.append(element('p',n.scope||n.notes||'Statement and scope extraction not recorded. Inspect the source reference.'));
panel.append(anchor('Read this node without JavaScript',nodePage(selected)));
panel.append(resumeSection(resumeProjection(data,selected,Date.now())));
panel.append(resumeSection(resumeProjection(data,selected,Date.now(),nodeStatus)));
const dl=element('dl',undefined,'atlas-axes');for(const a of evidenceAxes(n)){dl.append(element('dt',a.axis),element('dd',`${a.axis[0].toUpperCase()+a.axis.slice(1)} metadata ${a.state==='recorded'?'recorded':'not recorded'} · ${a.state}`));}panel.append(dl,element('p','These labels describe metadata in this graph snapshot. Evidence values, applicability and custody are separate. No explicit graph-to-artifact binding · Artifact roles: unknown · Custody: unknown.'));
const source=sourceForNode(data,n);if(source){panel.append(anchor('Immutable source reference (document bytes not acquired by this graph view)',sourceURL(source)));panel.append(element('p',`Git blob ${source.blob} · ${source.bytes} bytes in the pinned tree. Reference presence is not mathematical verification.`));}else panel.append(element('p',n.source?`Unresolved source reference: ${n.source}. No matched public file in this pinned source inventory.`:'Source reference not recorded.'));
for(const key of Object.keys(n).filter(k=>k.startsWith('review_'))){const value=n[key];const pinned=key==='review_source'?data.sources.find(s=>s.repository===data.graph.identity.repository&&s.path===value):null;if(pinned)panel.append(anchor('Recorded review source at the pinned commit',sourceURL(pinned)));else panel.append(linkRecord(`Recorded ${key}`,value&&typeof value==='object'?JSON.stringify(value):value));}
Expand Down
2 changes: 1 addition & 1 deletion docs/site/cite.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<link rel="stylesheet" href="style.css?site-release=6eb56e5c80ebf5811a77d0cb8583bf77dd8be44f170bebc9ae10721b2e6e9ab1"><link rel="stylesheet" href="brand.css?site-release=3e01852d8990ec3e9bbb351abc10e1a60e9e085041b7a7b1de95a1033089b751"><link rel="stylesheet" href="home.css?site-release=3745da1d9ea12f78ef0e350eb982d603d5e476db0b4cbf36746104a13fbf663e"><link rel="stylesheet" href="reference.css?site-release=f8709329ef33be5c92a2a53d27e906f2433836bc0a78324bfb8a15ecd2ffee48"><link rel="icon" type="image/svg+xml" href="brand/mark.svg?site-release=ef97bd43ea3d8999dbf26e5707d467987a745bf961cac2b3163f94062d087ba7"><meta name="color-scheme" content="dark light"><meta name="theme-color" media="(prefers-color-scheme: light)" content="#f6f8fc"><meta name="theme-color" media="(prefers-color-scheme: dark)" content="#07111f">
<script type="module" src="cite.mjs?site-release=d069bacebd8467fb69c0ae1de0abb85e6ac8b9b80ba152fc1c8d56fafa10e9bf"></script>
<link rel="stylesheet" href="current.css?site-release=9b70fee7f54345912905f33f4d15af39748b09c456bd88527b534cc9ceaae207">
<script type="module" src="current.mjs?site-release=8a66eb0ad9971fbffe07579998488e81195a024161995c3c4c7d4b34e1ec7262"></script>
<script type="module" src="current.mjs?site-release=c678bd088183b6548c4b094e8f7db287c9ab07f1ad2064737dc6eee9b82332d8"></script>
</head><body class="reader-home"><a class="skip-link" href="#main-content">Skip to content</a>
<header><a class="brand" href="index.html">UNIVERSAL LAW <span>MATHEMATICS IN THE OPEN</span></a><nav aria-label="Primary"><a href="index.html">Home</a><a href="explore.html">Explore</a><a href="research.html">Research</a><a href="workspace.html#inventory">Library</a><a href="dependencies.html#current-atlas">Mathematics</a></nav></header>
<nav class="reader-tools" aria-label="Research tools"><span class="reader-tools-label" aria-hidden="true">Research tools</span><a href="reproduce.html">Reproduce</a><a href="cite.html" aria-current="page">Cite</a></nav>
Expand Down
Loading
Loading