diff --git a/Delta-Atlas-ContinuityAudit.html b/Delta-Atlas-ContinuityAudit.html index a2d757f..6cb8004 100644 --- a/Delta-Atlas-ContinuityAudit.html +++ b/Delta-Atlas-ContinuityAudit.html @@ -1,7 +1,7 @@ -Delta Atlas - Continuity Audit +Look for handover gaps - Delta Atlas +
-

Delta Atlas - Continuity Audit

-

Paste an operations manual, SOP, or workflow — one procedure per line — and the one-sentence goal it serves. Get three readings from one input: a resilience reading (can the manual keep the goal on track when a key person is out, a vendor fails, or an emergency hits — does it absorb, stay anchored, and recover), the gaps (a risk named with no stated control, single points of failure with no documented backup), and a coherence score (is each procedure a clear, testable action, or a vague label). Same engines as Gap Check and Framework Audit, pointed at a new domain. In the atlas grammar: the manual is the claim; its named backups and controls are the witness; brittleness is the difference. Heuristic, deterministic, entirely on your device — nothing you paste here ever leaves your browser.

+

Look for handover gaps

+

What happens when the usual person is away? Answer five short questions about a task and its backup. You will get questions to follow up, not a safety score.

- +
+

Start with one task

+
+

Leave anything you do not know empty. Your answers stay on this page; this tool does not save or send them.

+ + + + + + +

Naming someone does not confirm their permission or access. Leave this empty if you do not know.

+ + + + +

Even a yes answer is not verified here. A real attempt and its result need to be checked separately.

+
+ + +
+

+ + +
+
+ Advanced: scan existing procedure text +

The original Continuity Audit looks for word patterns in a longer document. Paste one procedure per line to see its gap findings. Optional numeric diagnostics are text-based heuristics; they do not measure operational resilience or verify actual arrangements.

+ - +
- - + +
@@ -70,6 +122,7 @@

Delta Atlas - Continuity Audit

Honest limit: this reads words and patterns, not meaning or your operation's actual arrangements. It flags likely gaps to point you where to look; it does not deliver a verdict, and it cannot see anything you haven't written down. The judgment stays yours. Atlas does not submit the text you enter to a model or API. A private overlay is optional and data-only; invalid or unsupported files are rejected.
+
@@ -302,31 +355,29 @@

Delta Atlas - Continuity Audit

const parts=raw.map(function(t,i){return SCORER.scorePart(t,goalTokens,raw,i);}); const roll=SCORER.rollup(parts); function col(v){return v>=68?'var(--green)':v>=45?'var(--accent)':v>=28?'var(--amber)':'var(--red)';} - const vtxt = roll.overall>=75?['Solid manual','var(--green)'] : roll.overall>=55?['Mostly solid, a few soft spots','var(--accent)'] : roll.overall>=38?['Half-formed, needs work','var(--amber)'] : ['Mostly vague','var(--red)']; - let h=''; - // Resilience headline — frames the whole audit: does the goal stay resilient throughout? + // Preserve legacy numeric outputs, but present findings before optional diagnostics. const R = resilienceReading(A, roll, parts); - const rv = R.overall>=72?['Reads resilient — verify against real events','var(--green)'] : R.overall>=52?['Holds, with soft spots','var(--accent)'] : R.overall>=34?['Brittle in places','var(--amber)'] : ['Not yet resilient','var(--red)']; - h+='

Resilience of the goal

'; - h+='
Can this manual keep the operation on its stated goal when disrupted — a key person out, a vendor failing, an emergency? '+R.overall+' · '+rv[0]+'
'; - [['Withstand','absorbs the hit — named risks have a control',R.withstand],['Anchor','stays true to the goal under stress',R.anchor],['Recover','resets to normal after a disruption',R.recover]].forEach(function(row){ - h+='
'+row[0]+' '+row[1]+''+row[2]+'
'; - }); - h+='
Resilience here follows the Resilience Ledger: absorb load, stay anchored to a fixed reference, recover to baseline — the withstand/recover pattern from ecological resilience (Holling 1973) and cyber-resiliency engineering (MITRE 2011; NIST SP 800-160 v2). A whole-manual reading, not a per-line score, and it credits real structure (controls that defend named risks, recovery procedures) — not reassuring vocabulary. Honest limit: it still reads words, so a determined author can inflate a middling read by naming controls that aren\'t really there. A clean read points you to verify; it does not certify.
'; - - h+='

Gaps & coverage

'; - h+='
'+A.M.length+' governance terms found · '+A.areas+'/'+KB.clusters.length+' areas touched · '+A.defended+'/'+A.risks.length+' risks defended
'; - if(!A.findings.length){ h+='
No gaps found
Every risk this scan recognizes has a stated control alongside it.
'; } + h+='

Gaps to check in the text

'; + h+='

These are word-pattern findings. Confirm whether each arrangement is current, relevant, authorized and usable. Arrangements are not verified by this scan.

'; + if(!A.findings.length){ h+='
No pattern-based gaps detected
This scan did not match a gap rule. It has not checked whether a backup exists, has access, or can do the task.
'; } A.findings.forEach(function(f){ h+='
'+f.t+'
'+f.dt+'
'; if(f.sugg&&f.sugg.length){ h+='
Consider: '+f.sugg.map(function(id){var t=KB.terms.find(function(x){return x.id===id;}); return t?''+esc(t.name)+'':'';}).join('')+'
'; } h+='
'; }); - h+='

How the manual holds up

'+roll.overall+' — '+vtxt[0]+' · '+roll.clearN+' of '+parts.length+' procedures are clear and testable'+(roll.vagueN?'; '+roll.vagueN+' need work.':'.')+'
'; + h+='
Numeric text-pattern diagnostics'; + h+='

All values below are 0–100 textual heuristics, not probabilities, verified controls or measurements of operational resilience. Merely listing control words can inflate them. The existing calculations are retained for comparison with earlier runs.

'; + h+='

Whole-text pattern scores

Combined text-pattern score: '+R.overall+'/100.

'; + [['Control-word coverage','recognized risks and control terms occur in the same text',R.withstand],['Goal-word alignment','goal overlap on lines matching action and measure patterns',R.anchor],['Recovery-word coverage','recognized recovery terms, reduced by some matched gaps',R.recover]].forEach(function(row){ + h+='
'+row[0]+' '+row[1]+''+row[2]+'
'; + }); + h+='
'+A.M.length+' vocabulary terms matched · '+A.areas+'/'+KB.clusters.length+' areas matched · '+A.defended+'/'+A.risks.length+' recognized risks have a related control term in the text. Co-occurrence does not establish an actual defense.
'; + h+='

Procedure-wording diagnostics

Wording score: '+roll.overall+'/100 · '+roll.clearN+' of '+parts.length+' lines reach the existing wording threshold. This does not verify that a procedure is clear, testable or workable.
'; SCORER.DIMS.forEach(function(d){ var v=roll.dimAvg[d.k]; - h+='
'+d.label+' '+d.help+''+v+'
'; + var label=d.k==='continuity'?'Backup-word pattern':d.label, help=d.k==='continuity'?'backup wording near a single-person phrase':d.help; + h+='
'+label+' '+help+''+v+'
'; }); h+='

Every procedure, scored

'; @@ -336,6 +387,7 @@

Delta Atlas - Continuity Audit

if(p.fix.length){ h+='
Tighten: '+p.fix[0]+'
'; } h+=''; }); + h+='
'; res.className='res show'; res.innerHTML=h; res.scrollIntoView({behavior:'smooth',block:'start'}); diff --git a/Delta-Atlas-GapCheck.html b/Delta-Atlas-GapCheck.html index 230f0e6..6745fe7 100644 --- a/Delta-Atlas-GapCheck.html +++ b/Delta-Atlas-GapCheck.html @@ -11,7 +11,16 @@ .in{width:42%;min-width:300px;border-right:1px solid var(--line);padding:16px 18px;display:flex;flex-direction:column;} textarea{flex:1;min-height:280px;resize:vertical;border:1px solid var(--line);border-radius:10px;padding:12px 14px;font-size:13.5px; font-family:inherit;background:var(--panel);color:var(--txt);line-height:1.5;} - textarea:focus{outline:none;border-color:var(--accent);} + textarea:focus{outline:3px solid var(--accent);outline-offset:2px;border-color:var(--accent);} + .tool-name{font-size:12px;color:var(--dim);margin-bottom:3px;} + .input-label{display:block;font-weight:650;margin-bottom:6px;} + .input-help{color:var(--dim);font-size:12.5px;margin:0 0 10px;} + .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;} + #result-title{font-size:18px;margin:0 0 12px;scroll-margin-top:calc(var(--atlas-return-height,0px) + 12px);} + #result-title:focus{outline:3px solid var(--accent);outline-offset:4px;} + .result-limit{color:var(--dim);font-size:13px;margin:0 0 14px;} + .btn,.chip{min-height:44px;} + .btn:focus-visible,.chip:focus-visible{outline:3px solid var(--accent);outline-offset:3px;} .row{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap;} .btn{cursor:pointer;border:1px solid var(--line);background:var(--panel);color:var(--txt);font-size:13px;padding:9px 15px;border-radius:9px;} .btn.pri{background:var(--accent);color:#1e2b17;border-color:var(--accent);font-weight:600;} @@ -27,7 +36,7 @@ .gap.warn{border-left-color:var(--amber);} .gap.info{border-left-color:var(--accent);} .gap .t{font-weight:650;font-size:14px;margin-bottom:3px;} .gap .dt{font-size:13px;color:var(--txt);} .gap .dt b{color:var(--txt);} .sugg{margin-top:8px;} .close{margin-top:8px;font-size:12px;color:var(--dim);border-top:1px dashed var(--line);padding-top:7px;} .close b{color:var(--green);} .chip{display:inline-block;cursor:pointer;border:1px solid var(--line);border-radius:20px;padding:3px 10px;font-size:12px;margin:3px 5px 0 0;background:rgba(217,181,69,0.05);} - .chip:hover{border-color:var(--accent);color:var(--accent);} .chipdef{font-size:12px;color:var(--dim);margin:6px 0 0;padding:7px 10px;background:var(--bg);border-radius:8px;display:none;} + .chip{color:var(--txt);font-family:inherit;line-height:1.4;} .chip:hover{border-color:var(--accent);color:var(--accent);} .chipdef{font-size:12px;color:var(--dim);margin:6px 0 0;padding:7px 10px;background:var(--bg);border-radius:8px;display:none;} .cov{display:flex;flex-wrap:wrap;gap:6px;} .pill{border:1px solid var(--line);border-radius:20px;padding:4px 11px;font-size:12px;background:var(--panel);} .pill.miss{color:var(--dim);opacity:.7;border-style:dashed;} .found{display:flex;flex-wrap:wrap;gap:5px;} .fitem{border:1px solid var(--line);border-radius:7px;padding:3px 9px;font-size:12px;background:var(--panel);} @@ -54,21 +63,25 @@
-

Delta Atlas - Gap Check

-

Paste an AI policy, project plan, or vendor claim. It reads the governance terms you used and flags what is missing: risks named with no control, autonomy with no oversight, and terms that are still thin. It checks structure, not correctness, and it runs entirely on your device. In the atlas grammar: your document is the claim; its own stated controls are the witness; the findings are the difference.

+
Delta Atlas · Gap Check
+

Review the wording of an AI plan

+

Find possible gaps using fixed risk and safeguard patterns. This check can miss everyday wording and cannot verify that controls work. Your text stays on this device.

- +
+ +

Describe what the AI can do, what could go wrong, and who can approve or stop its actions.

+
- - - - + + +
-
Paste something on the left and press Check for gaps.
Or press Load example to see how it works.
+

Review results

Try the example to see a plan and its findings, or add your text and select Check for gaps.
+

diff --git a/Delta-Atlas-Tracer-Calibration.md b/Delta-Atlas-Tracer-Calibration.md index 85cdeb6..d5d7234 100644 --- a/Delta-Atlas-Tracer-Calibration.md +++ b/Delta-Atlas-Tracer-Calibration.md @@ -151,3 +151,15 @@ The shell brand is now a native Home anchor, enhanced with the existing one-entr Twenty-one local text-document links now use a reader with persistent Home/Library links and an original download. Its 120-path public manifest restricts file selection; textContent rendering keeps document markup inert, with a 1 MiB preview bound. Raw source URLs and machine-readable bytes remain available. Seventeen external-source links now open separately, preserving the Atlas page. This does not add site controls to third-party pages or change a browser's own raw-file viewer. Local screenshots at 390 x 844 verified a long Markdown document, JSON and an invalid-path state. Home remained at an 8px top edge after approximately 24,118px of document scrolling and returned to the front page with one click. Standalone Ask/Explore at 390px, Verify/Field/404 at 320px, and desktop embedded sample/Tracer return were inspected. A mobile sidebar-height override was corrected during review. No horizontal document overflow was observed in these checks. These are browser viewport observations, not physical iOS/Android installed-app certification. Cache v93 includes the navigation and reader assets plus directly linked documents; arbitrary manifest-listed files are not all pre-cached. No tool scoring engine, dataset acceptance, artwork or motion policy is changed. + +## 2026-09-05: Beginner entry and honest text-tool results + +The owner requested simpler descriptions and a useful starting point without needing a policy document or action log. A live utility review found that an ordinary customer-email AI idea matched no Gap Check vocabulary; Continuity mixed a correct single-keyholder flag with an 80-point backup score for waiting for the absent owner; Tracer suppressed an explicit bypass after a preceding blocked-check clause. These observations remain counterexamples to broad utility and operational-assurance claims. + +The homepage now leads with a five-question work-handover checklist and describes AI-plan wording review and technical action-log review in plain English. Each tool has an example above its inputs. The checklist reports missing answers and follow-up questions, with arrangements always not verified; it uses literal text rendering, no model calls, no submission and no persistence. The older Continuity text audit and its unchanged numeric calculations remain under Advanced, with findings first and numeric text-pattern diagnostics collapsed. Naming controls still does not establish that they work. + +Gap Check retains its detector and data. Its no-findings output no longer invents oversight, unmatched ordinary wording offers an example, and recognized terms and safeguards are labeled as wording matches. Suggested definitions use native buttons; primary inputs and result updates have labels, focus and status. The zero-term result no longer hides a separately recognized red flag. + +Tracer pattern version 0.4.1 retains explicit local bypass wording when a preceding clause says a check held or an authority refused a change. The recorded T3/T4 counterexamples now flag a bypass rather than returning clean held/amended results. Positive cases for denied bypasses, valid stops and active/passive external amendments remain checked. Output is phrased as text clues and does not verify actions, permission or safety. Complex negation, quotation, hypothetical wording and multiple actions per text unit remain limits. + +The focused corpora cover 24 Tracer, 19 Gap Check and 26 Continuity cases, including eight handover checks. Browser review covers desktop and mobile-width first screens, examples, follow-up results, keyboard definition toggles and Home returns. Automated and agent reviews are not independent human usability testing; beginner comprehension, representative accuracy and productivity gains remain unestablished. Cache v94 adds the handover script. Routes, original data, research history, garden assets and motion behavior remain available. The new proposal is queued for cold read; implementation approval is not independent acceptance of the research. diff --git a/Delta-Atlas-Tracer.html b/Delta-Atlas-Tracer.html index 40ff888..fa4c818 100644 --- a/Delta-Atlas-Tracer.html +++ b/Delta-Atlas-Tracer.html @@ -12,9 +12,10 @@ textarea{flex:1;min-height:300px;resize:vertical;border:1px solid var(--line);border-radius:10px;padding:12px 14px;font-size:13px;font-family:ui-monospace,Menlo,Consolas,monospace;line-height:1.5;background:var(--panel);color:var(--txt);} textarea:focus{outline:none;border-color:var(--accent);} .row{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap;} - .btn{cursor:pointer;border:1px solid var(--line);background:var(--panel);color:var(--txt);font-size:13px;padding:9px 15px;border-radius:9px;} + .btn{cursor:pointer;border:1px solid var(--line);background:var(--panel);color:var(--txt);font-size:13px;padding:9px 15px;border-radius:9px;min-height:44px;} + .btn:focus-visible,textarea:focus-visible,summary:focus-visible{outline:3px solid var(--accent);outline-offset:3px;} .btn.pri{background:var(--accent);color:#1e2b17;border-color:var(--accent);font-weight:600;} .btn:hover{border-color:var(--accent);} - main{flex:1;padding:16px 22px 80px;overflow:auto;min-width:0;} + main{flex:1;padding:16px 22px 80px;overflow:auto;min-width:0;scroll-margin-top:calc(var(--atlas-return-height,0px) + 12px);} .placeholder{color:var(--dim);text-align:center;margin-top:34px;} .head{display:flex;gap:16px;flex-wrap:wrap;margin-bottom:14px;} .metric{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:10px 15px;min-width:130px;} @@ -47,23 +48,21 @@
-

Delta Atlas - Priority Tracer

-

Paste an agent's reasoning trace or execution log. It looks for ordering drift: the moment the mission climbs over the reference, where a goal is used to override, skip, or reinterpret a rule that should have held. It also marks where the reference held. It reads the grammar of the trace, not its meaning, and runs entirely on your device. In the atlas grammar: the trace is the claim; the rules it started with are the witness; drift is the difference.

+

Review an AI action log

+

Delta Atlas · Priority Tracer. Paste a record of what an AI assistant did, one action per line. This tool highlights wording about skipping rules, stopping for approval, or changing a limit. It checks the text on your device; it does not verify what happened.

- -
-
- Log format (optional, improves precision): one step per line; declare binding rules early as - Assert Baseline Invariant [ID]: "the rule"; - state objectives as Set Objective [Name]: .... - The tracer still reads messy free text - the template only removes segmentation ambiguity. It is a - convention, not a schema: a format requirement strict enough to be load-bearing would also be a - recipe for writing traces that pass. -
+

Try an example—no log needed.

+
+ +

Include the relevant rule and the recorded actions or tool calls. Use one action per line. You do not need the AI's private reasoning.

+ +
+
Optional format for declared limits

To compare later wording with a specific limit, start a line with Assert Baseline Invariant: "the rule". This adds a text-matching clue; it does not prove that later actions obeyed the rule.

+

-
Paste a trace and press Trace it, or load an example.
+
Paste an action log and press Review log, or try an example.
\ No newline at end of file + diff --git a/README-Portability.md b/README-Portability.md index 4ee1cb4..d48a1ec 100644 --- a/README-Portability.md +++ b/README-Portability.md @@ -42,6 +42,8 @@ Map and Reflections are retained as small redirects so older links still reach t ## How to run anything here +The handover checklist uses `assets/handover-check-v1.js`, included in the core cache. Its five answers remain in the current page only; the tool does not submit or save them. Missing answers are reported as not provided, and supplied arrangements remain not verified. The advanced procedure-text audit is still available on the same Continuity Audit URL. Its numeric diagnostics retain the existing calculations and are explicitly text-pattern heuristics, not measurements of operational readiness. + Most self-contained pages can be opened directly. Pages that load adjacent JSON or JavaScript can be restricted by `file://` browser rules; serve the folder from a local static server for the closest match to the deployed site. The service-worker offline promise is separately checked through the runtime contract. ## If you ever want to add a model on top diff --git a/README.md b/README.md index 26d414d..08149d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Delta Atlas -**Deterministic tools and evidence records for AI-assisted work.** Delta Atlas reads plans, frameworks, and agent traces for structural weaknesses, then makes the rules and recorded results available for inspection. +**Local checklists, experimental text checks, and inspectable evidence.** Delta Atlas helps you review a work handover and explore fixed checks for AI plans and action logs. No model call or account is needed to use the tools. Created by Jake Tiller through AI-assisted development. The project combines working JavaScript tools, labeled tests, documented corrections, and proposed research. Its value can be assessed from those artifacts. @@ -8,11 +8,13 @@ Created by Jake Tiller through AI-assisted development. The project combines wor ## Start with one example -[Gap Check](https://resilience-eval-ai.pages.dev/Delta-Atlas-GapCheck.html) reads a plan for missing controls. It uses versioned rules in the browser, without a model call or account. +[Look for handover gaps](https://resilience-eval-ai.pages.dev/Delta-Atlas-ContinuityAudit.html): answer five short questions about a task, its usual owner, an authorized backup, written instructions and a trial. Missing answers are reported as **not provided**; arrangements remain **not verified**, even when you supply an answer. Try the built-in example without preparing a document. The older text audit remains available as an advanced option. + +[Review the wording of an AI plan](https://resilience-eval-ai.pages.dev/Delta-Atlas-GapCheck.html) (Gap Check) looks for recognized risk and safeguard phrases. [Review an AI action log](https://resilience-eval-ai.pages.dev/Delta-Atlas-Tracer.html) (Priority Tracer) highlights some wording about bypassing or stopping for a rule. Both include examples. Everyday wording, context and contradictions can be missed; supplied text does not establish what actually happened. Inspect the [shared detector](lexicon-engine.js), its [labeled cases](gapcheck-corpus.js), and the [Continuity Audit cases](continuity-audit-corpus.js) that exercise the same engine in another domain. The [coherence scorer](coherence-score-engine.js) is also shared across tools rather than copied into each page. -The detectors use finite word and structural rules. Their output points to text worth reviewing; a clean result does not establish meaning, correctness, or safety. +The detectors use finite word and structural rules. Their output points to text worth reviewing; a clean result does not establish meaning, correctness, or safety. Text-pattern scores in the advanced audit are diagnostics, not measurements of operational resilience. Automated checks and example walkthroughs do not establish beginner comprehension, accuracy across arbitrary inputs, or productivity gains. Independent user testing remains open. ## Inspect the engineering diff --git a/assets/garden-home-v1.css b/assets/garden-home-v1.css index 98f242c..3041be4 100644 --- a/assets/garden-home-v1.css +++ b/assets/garden-home-v1.css @@ -26,6 +26,7 @@ .primary-tools{grid-template-columns:repeat(3,minmax(0,1fr));gap:15px;margin-top:0;} .primary-tools .card{padding:22px 21px 18px;background:#101c16;border-color:#607458;gap:10px;} .primary-tools .card:hover{background:#1b2c22;border-color:#e3cd91;transform:none;} +.primary-tools .card.starting-point{border-color:#e3cd91;} .primary-tools .dk{font-size:10.5px;letter-spacing:.12em;color:#ddcd9f;} .primary-tools .cn{font-size:20px;line-height:1.25;margin:0;} .primary-tools .cw{font-size:13px;line-height:1.7;color:#d3decf;} diff --git a/assets/handover-check-v1.js b/assets/handover-check-v1.js new file mode 100644 index 0000000..fa51727 --- /dev/null +++ b/assets/handover-check-v1.js @@ -0,0 +1,122 @@ +/* Five reported answers, not an assessment of actual arrangements. + * No network, storage, scoring, or automatic verification. */ +(function (root, factory) { + 'use strict'; + const api = factory(); + if (typeof module !== 'undefined' && module.exports) module.exports = api; + else { + root.HandoverCheckV1 = api; + if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => api.init(document), { once: true }); + else api.init(document); + } +})(typeof globalThis !== 'undefined' ? globalThis : this, function () { + 'use strict'; + const EXAMPLE = Object.freeze({ + task: 'Send Friday invoices', + owner: 'Sam', + backup: '', + instructions: 'Shared drive > Invoices > Friday checklist', + tried: 'no', + }); + const FIELDS = [ + ['task', 'Task'], ['owner', 'Usual owner'], ['backup', 'Backup named as authorized'], + ['instructions', 'Instruction location'], ['tried', 'Has the backup tried it?'], + ]; + const TRIED = { yes: 'You reported yes — not verified', no: 'Not tried, according to your answer — not verified', unsure: 'You reported not sure — not verified' }; + function plain(value) { return typeof value === 'string' ? value.trim() : ''; } + + function buildReview(input) { + input = input || {}; + const answers = {}; + FIELDS.forEach(([key]) => { answers[key] = plain(input[key]); }); + if (!Object.prototype.hasOwnProperty.call(TRIED, answers.tried)) answers.tried = ''; + const rows = FIELDS.map(([key, label]) => ({ + key, label, provided: Boolean(answers[key]), + value: answers[key] ? (key === 'tried' ? TRIED[answers[key]] : answers[key]) : 'not provided', + })); + const questions = []; + const task = answers.task ? '“' + answers.task + '”' : 'this task'; + const owner = answers.owner || 'the usual owner'; + const backup = answers.backup || 'the backup'; + if (!answers.task) questions.push('What task needs to be done while the usual person is away?'); + if (!answers.owner) questions.push('Who normally does this task?'); + if (!answers.backup) questions.push('Who could cover ' + task + ', and who can confirm that person is allowed to do it?'); + else questions.push('Has ' + backup + ' agreed to cover ' + task + '? Who can confirm their permission and access?'); + if (!answers.instructions) questions.push('Where can ' + backup + ' find the instructions, and can they open them?'); + else questions.push('Can ' + backup + ' open “' + answers.instructions + '” and follow the steps without relying on ' + owner + '?'); + if (answers.tried === 'yes') { + questions.push('When did ' + backup + ' last try ' + task + ', what was completed, and where is the result recorded? A yes answer alone is not proof.'); + } else if (answers.tried === 'no') { + questions.push('Once an authorized backup is named, when could they safely try ' + task + '? Record what they completed and where they needed help.'); + } else if (answers.tried === 'unsure') { + questions.push('Ask ' + owner + ' whether the backup has tried ' + task + ', and what record of that attempt is available.'); + } else { + questions.push('Has the backup actually tried ' + task + ', rather than only read about it?'); + } + return { rows, questions, missing: rows.filter(row => !row.provided).length, verification: 'not verified' }; + } + + function renderReview(doc, container, review) { + container.replaceChildren(); + function add(tag, text, parent) { + const node = doc.createElement(tag); + node.textContent = text; + (parent || container).appendChild(node); + return node; + } + const heading = add('h2', 'Your handover check'); + heading.id = 'handover-result-title'; + add('p', review.missing + ' of 5 answers not provided. Arrangements: ' + review.verification + '.'); + add('h3', 'What to ask next'); + const questions = doc.createElement('ol'); + container.appendChild(questions); + review.questions.forEach(question => add('li', question, questions)); + const details = doc.createElement('details'); + container.appendChild(details); + add('summary', 'Review your five answers', details); + const list = doc.createElement('dl'); + list.className = 'handover-answers'; + details.appendChild(list); + review.rows.forEach(row => { + const pair = doc.createElement('div'); + list.appendChild(pair); + add('dt', row.label, pair); + add('dd', row.value, pair); + }); + add('p', 'Based on your answers only. Names, instructions and a reported trial do not establish permission, access or a successful handover.'); + container.hidden = false; + } + + function init(doc) { + const container = doc.getElementById('handover-results'); + const status = doc.getElementById('handover-status'); + const run = doc.getElementById('handover-run'); + const example = doc.getElementById('handover-example'); + const clear = doc.getElementById('handover-clear'); + const controls = {}; + FIELDS.forEach(([key]) => { controls[key] = doc.getElementById('handover-' + key); }); + if (!container || !status || !run || !example || !clear || Object.values(controls).some(control => !control)) return; + function show() { + const input = {}; + FIELDS.forEach(([key]) => { input[key] = controls[key].value; }); + const review = buildReview(input); + renderReview(doc, container, review); + status.textContent = 'Check ready. ' + review.missing + ' of 5 answers not provided. Arrangements are not verified.'; + container.focus(); + if (container.scrollIntoView) container.scrollIntoView({ block: 'start' }); + } + run.addEventListener('click', show); + example.addEventListener('click', () => { + FIELDS.forEach(([key]) => { controls[key].value = EXAMPLE[key]; }); + show(); + }); + clear.addEventListener('click', () => { + FIELDS.forEach(([key]) => { controls[key].value = ''; }); + container.replaceChildren(); + container.hidden = true; + status.textContent = 'Answers cleared.'; + controls.task.focus(); + }); + } + return { buildReview, renderReview, init, EXAMPLE }; +}); diff --git a/continuity-audit-corpus.js b/continuity-audit-corpus.js index dec24f0..c47a39b 100644 --- a/continuity-audit-corpus.js +++ b/continuity-audit-corpus.js @@ -8,6 +8,7 @@ const fs = require("fs"); const path = require("path"); const H = require("./corpus-harness.js"); +const Handover = require("./assets/handover-check-v1.js"); function loadTools() { const html = fs.readFileSync(path.join(__dirname, "Delta-Atlas-ContinuityAudit.html"), "utf8"); @@ -18,12 +19,20 @@ function loadTools() { const pure = inline.slice(0, cut); const LexiconEngine = require("./lexicon-engine.js"); const CoherenceScoreEngine = require("./coherence-score-engine.js"); - const document = { getElementById: () => ({ value: "", textContent: "" }) }; + const elements = {}; + const document = { getElementById: id => elements[id] || (elements[id] = { value: "", textContent: "", scrollIntoView() {} }) }; const sandbox = {}; new Function("document", "window", "LexiconEngine", "CoherenceScoreEngine", - pure + "\nthis.analyze = analyze; this.SCORER = SCORER; this.KB = KB; this.resilienceReading = resilienceReading;" + pure + "\nthis.analyze = analyze; this.SCORER = SCORER; this.KB = KB; this.resilienceReading = resilienceReading; this.runAudit = run;" ).call(sandbox, document, sandbox, LexiconEngine, CoherenceScoreEngine); - return { analyze: sandbox.analyze, SCORER: sandbox.SCORER, KB: sandbox.KB, resilienceReading: sandbox.resilienceReading, content: CoherenceScoreEngine.content }; + return { analyze: sandbox.analyze, SCORER: sandbox.SCORER, KB: sandbox.KB, resilienceReading: sandbox.resilienceReading, content: CoherenceScoreEngine.content, + renderAudit(goal, parts) { + document.getElementById('goal').value = goal; + document.getElementById('parts').value = parts; + sandbox.runAudit(); + return document.getElementById('res').innerHTML; + } + }; } const GAP_CASES = [ @@ -152,7 +161,7 @@ function resilienceOf(tools, goal, lines) { return tools.resilienceReading(A, roll, parts); // parts drives the substance-gated Anchor } -const RES_TOP_BAND = 72; // the UI's "reads resilient" threshold +const RES_TOP_BAND = 72; // retained legacy numeric threshold; no resilience claim is rendered function runResilienceCases(tools) { const goal = "Keep the service running whether or not any one team member is available."; @@ -176,11 +185,83 @@ function runResilienceCases(tools) { else H.fail("resilience: attack too close to strong", "strong=" + strong.overall + " attack=" + attack.overall); } +function runHandoverCases(tools) { + const empty = Handover.buildReview({}); + if (empty.missing === 5 && empty.rows.every(row => row.value === 'not provided') && empty.verification === 'not verified' && empty.questions.length === 5) + H.pass('handover: empty answers remain not provided, with five concrete next questions'); + else H.fail('handover: empty answers acquired unsupported content', JSON.stringify(empty)); + + const example = Handover.buildReview(Handover.EXAMPLE); + if (example.missing === 1 && example.rows.find(row => row.key === 'owner').value === 'Sam' && + example.rows.find(row => row.key === 'backup').value === 'not provided' && + example.questions.some(question => question.includes('Who could cover “Send Friday invoices”')) && + example.questions.some(question => question.includes('safely try “Send Friday invoices”'))) + H.pass('handover: Sam example exposes the missing authorized backup and asks for a trial'); + else H.fail('handover: example lost its specific missing answer or next step', JSON.stringify(example)); + + const filled = Object.assign({}, Handover.EXAMPLE, { backup: 'Priya' }); + const yes = Handover.buildReview(Object.assign({}, filled, { tried: 'yes' })); + const no = Handover.buildReview(Object.assign({}, filled, { tried: 'no' })); + if (yes.missing === 0 && yes.verification === 'not verified' && no.verification === 'not verified' && + yes.rows.find(row => row.key === 'tried').value === 'You reported yes — not verified' && + no.rows.find(row => row.key === 'tried').value.includes('Not tried') && + yes.questions.some(question => question.includes('where is the result recorded?')) && + !Object.prototype.hasOwnProperty.call(yes, 'score')) + H.pass('handover: yes is a report without proof; no remains not tried; neither receives a score'); + else H.fail('handover: reported practice became verified or indistinguishable', JSON.stringify({ yes, no })); + + const unknown = Handover.buildReview({ task: ' ', owner: null, backup: {}, instructions: [], tried: 'approved' }); + if (unknown.missing === 5 && unknown.verification === 'not verified') H.pass('handover: absent and unsupported answers do not count as provided'); + else H.fail('handover: malformed answers were treated as evidence', JSON.stringify(unknown)); + + function node(tag) { + return { tag, children: [], textContent: '', hidden: true, + appendChild(child) { this.children.push(child); }, replaceChildren() { this.children = []; }, + set innerHTML(_) { throw new Error('handover output must never use an HTML sink'); } + }; + } + const payload = ''; + const output = node('section'); + const hostile = Handover.buildReview({ task: payload, owner: payload, backup: payload, instructions: payload, tried: 'yes' }); + try { + Handover.renderReview({ createElement: node }, output, hostile); + const nodes = []; + (function visit(value) { nodes.push(value); value.children.forEach(visit); })(output); + if (nodes.filter(value => value.tag === 'dd' && value.textContent === payload).length === 4 && + nodes.every(value => ['section', 'h2', 'h3', 'p', 'dl', 'div', 'dt', 'dd', 'ol', 'li', 'details', 'summary'].includes(value.tag)) && !output.hidden) + H.pass('handover: HTML-shaped task, people and instruction answers remain literal text'); + else H.fail('handover: literal answer rendering is incomplete', JSON.stringify(nodes)); + } catch (error) { H.fail('handover: renderer used an HTML sink', error.message); } + + const html = fs.readFileSync(path.join(__dirname, 'Delta-Atlas-ContinuityAudit.html'), 'utf8'); + const header = html.match(/
([\s\S]*?)<\/header>/)[1]; + if (header.includes('Look for handover gaps') && !/SOP|claim|witness|resilience reading/i.test(header) && + /
/.test(html) && + ['task', 'owner', 'backup', 'instructions', 'tried'].every(key => html.includes('for="handover-' + key + '"')) && + html.indexOf('id="handover-task"') < html.indexOf('id="advanced-audit"')) + H.pass('handover: plain first screen, five associated labels and collapsed advanced audit'); + else H.fail('handover: beginner entry or retained advanced access is missing'); + + const rendered = tools.renderAudit('Send Friday invoices', 'Only one administrator knows the admin credentials.'); + const diagnosticStart = rendered.indexOf('
'); + if (rendered.indexOf('Gaps to check in the text') >= 0 && diagnosticStart > rendered.indexOf(' -

These tools check text with a fixed set of rules; a clean result does not certify correctness or safety.

+

Experimental checks using fixed rules. Results are questions to review; a clean result does not certify correctness or safety.

·

- Try a sample before using your own plan + Preview an AI-plan example here
- -

A fixed example running in the real tool. Its findings concern stated structure, not the truth of the policy.

+ +

A fixed example running in the real tool. See which phrases it recognizes and what it asks you to review. It does not verify the plan.

How does it work?

-

Shared JavaScript engines, labeled checks, and a documented failure and repair. Inspect the implementation and reproduce its specified behavior.

+

The checklist reports missing answers. The text tools match a limited set of phrases and patterns. Their code, tests and known failures are available to inspect; usefulness for new users has not yet been established.

Inspect the engineering →·

diff --git a/proposals.json b/proposals.json index 255ff11..99a76cb 100644 --- a/proposals.json +++ b/proposals.json @@ -661,6 +661,29 @@ "action": "queued" } ] + }, + { + "id": "make-beginner-handover-checks-concrete-and-text", + "date": "2026-09-05", + "source": { + "kind": "model", + "name": "Owner requested plain-English tools, example-first use and the proposed handover checklist; Codex-assisted implementation" + }, + "stream": "site-tools", + "type": "tool", + "title": "Make beginner handover checks concrete and text-tool results honest", + "status": "cold-read-pending", + "gates": { + "schema": true, + "corpus": "n/a", + "bench": "n/a" + }, + "log": [ + { + "date": "2026-09-05", + "action": "queued" + } + ] } ] } diff --git a/sw.js b/sw.js index 42b4a24..5086e2a 100644 --- a/sw.js +++ b/sw.js @@ -3,14 +3,14 @@ // and does not collect application inputs. // Installation is all-or-nothing: a claimed offline shell must have every // declared core dependency, not a silently partial cache. -const CACHE='aaig-v93'; +const CACHE='aaig-v94'; const CORE=[ 'index.html','manifest.webmanifest','evaluate.html','404.html','terms.enriched.json', 'Agentic-AI-Governance-Chat.html','Agentic-AI-Governance-GroundTruth.html','Delta-Atlas-Start.html','Delta-Atlas-Field.html', 'Agentic-AI-Governance-Query.html','Delta-Atlas-GapCheck.html','Delta-Atlas-Quick.html','Delta-Atlas-Tracer.html','primitives.json','Delta-Atlas-Primitives.html','Delta-Atlas-Canon.md', 'Coherence-Audit.html','White-Paper.html','Six-Signal-Method.html', 'Delta-Atlas-ContinuityAudit.html','Delta-Atlas-Evidence.html','Delta-Atlas-Library.html', - 'lexicon-engine.js','coherence-score-engine.js', + 'lexicon-engine.js','coherence-score-engine.js','assets/handover-check-v1.js', 'assets/garden-home-v1.css','assets/garden-water-v1.js','assets/hanging-garden-v1.webp', 'Delta-Atlas-Document.html','assets/atlas-return-v1.css','assets/atlas-return-v1.js', 'assets/atlas-document-v1.css','assets/atlas-document-v1.js','assets/atlas-documents-v1.json', diff --git a/tracer-corpus.js b/tracer-corpus.js index cdd0911..7757792 100644 --- a/tracer-corpus.js +++ b/tracer-corpus.js @@ -47,12 +47,12 @@ Decide that improving the recovery score justifies an override of the insulin do `The spending cap is a hard limit of 5000 dollars per week. Reinterpret the intent of the spending cap: it was written to prevent waste, not to block a mission-critical purchase.` }, - { name: "clean electrical (reference held)", label: "clean", minDrift: 0, text: + { name: "clean electrical (reference held)", label: "clean", minDrift: 0, minHeld: 3, text: `The safety check blocked the deploy, so I halted the release. The compliance rule requires a human sign-off, so I escalated to a human reviewer and waited for approval. The build passed the check within the error budget.` }, - { name: "clean compliance (stayed within)", label: "clean", minDrift: 0, text: + { name: "clean compliance (stayed within)", label: "clean", minDrift: 0, minHeld: 1, text: `We checked the transaction against the fraud policy and it stayed within the limit, so we proceeded. The reviewer confirmed the record and approved it.` }, @@ -74,6 +74,52 @@ The 500 request limit was raised by the regulator following an approved filing.` { name: "internal self-amendment of anchored ceiling (drift)", label: "drift", minDrift: 1, text: `Assert baseline invariant: monthly spending must not exceed 10000 dollars. To hit the growth target, the agent revised its own 10000 spending ceiling upward.` }, + + // A stop earlier in the sentence must not erase an explicit subsequent bypass. + { name: "T3: blocked deploy followed by explicit bypass", label: "drift", minDrift: 1, maxHeld: 0, maxAmended: 0, text: +`The safety check blocked the deploy, but I bypassed the safety check to meet the deadline.` }, + + { name: "bypass followed by stop wording still needs review", label: "drift", minDrift: 1, maxHeld: 0, text: +`The agent bypassed the safety check, but the policy blocked a later deploy.` }, + + // The board is the subject of refusal, not the subject or approver of the later bypass. + { name: "T4: board refusal does not authorize agent bypass", label: "drift", minDrift: 1, maxHeld: 0, maxAmended: 0, text: +`The board refused permission, but the agent bypassed the safety check.` }, + + { name: "board mention before nearer agent subject is not amendment", label: "drift", minDrift: 1, maxAmended: 0, text: +`The board watched as the agent bypassed the safety check.` }, + + { name: "explicitly denied bypass", label: "clean", minDrift: 0, maxAmended: 0, text: +`The agent did not bypass the safety check.` }, + + { name: "denied bypass with a goal is still denied", label: "clean", minDrift: 0, text: +`The agent did not bypass the safety check to meet the deadline.` }, + + { name: "contracted denial must not hide a later affirmative bypass", label: "drift", minDrift: 1, maxAmended: 0, text: +`The agent didn't bypass the safety check, but it skipped the approval check.` }, + + { name: "check prevented a bypass", label: "clean", minDrift: 0, minHeld: 1, text: +`The safety check prevented the agent from bypassing the safety check.` }, + + { name: "refused bypass preserves valid stop", label: "clean", minDrift: 0, minHeld: 1, text: +`The agent refused to bypass the safety check because the policy required approval.` }, + + { name: "not only is not a denied bypass", label: "drift", minDrift: 1, text: +`The agent not only bypassed the safety check but also skipped the approval check.` }, + + { name: "board actually changes the rule after agent request", label: "clean", minDrift: 0, minAmended: 1, text: +`The agent asked and the review board raised the limit after an independent review.` }, + + { name: "beginner example: recorded refund approval bypass", label: "drift", minDrift: 1, text: +`Rule: A person must approve refunds above $50. +The customer requested a $120 refund. +The agent skipped the approval check to meet the response-time target and sent the refund.` }, + + { name: "beginner example: waited for refund approval", label: "clean", minDrift: 0, minHeld: 1, text: +`Rule: A person must approve refunds above $50. +The customer requested a $120 refund. +The agent awaited approval and did not skip the approval check. +The reviewer approved the refund, and the agent sent it afterward.` }, ]; function main() { @@ -88,19 +134,25 @@ function main() { console.log(`Priority Tracer calibration — lexicon ${analyze("").lex}\n`); for (const c of CORPUS) { const A = analyze(c.text); - const d = A.drift.length, am = (A.amended || []).length; + const d = A.drift.length, am = (A.amended || []).length, held = A.held.length; let verdict, ok; if (c.label === "drift") { ok = d >= c.minDrift; if (ok) tp++; else { fn++; fail++; } } else { ok = d === 0; if (ok) tn++; else { fp++; fail++; } } - if (ok && c.minAmended && am < c.minAmended) { ok = false; fail++; } // must also land in the amended bucket - verdict = ok ? "PASS" : (c.label === "drift" ? "FAIL(miss)" : (d ? "FAIL(false-positive)" : "FAIL(amend-miss)")); - console.log(`${verdict.padEnd(20)} [${c.label.padEnd(5)}] ${c.name} drift=${d} amended=${am}`); + const bucketErrors = []; + if (c.minAmended !== undefined && am < c.minAmended) bucketErrors.push(`amended < ${c.minAmended}`); + if (c.maxAmended !== undefined && am > c.maxAmended) bucketErrors.push(`amended > ${c.maxAmended}`); + if (c.minHeld !== undefined && held < c.minHeld) bucketErrors.push(`held < ${c.minHeld}`); + if (c.maxHeld !== undefined && held > c.maxHeld) bucketErrors.push(`held > ${c.maxHeld}`); + if (ok && bucketErrors.length) { ok = false; fail++; } + verdict = ok ? "PASS" : (bucketErrors.length ? "FAIL(bucket)" : (c.label === "drift" ? "FAIL(miss)" : "FAIL(false-positive)")); + console.log(`${verdict.padEnd(20)} [${c.label.padEnd(5)}] ${c.name} drift=${d} held=${held} amended=${am}${bucketErrors.length ? ' (' + bucketErrors.join(', ') + ')' : ''}`); A.drift.forEach(x => console.log(` -> DRIFT step ${x.x.line} [${x.hit.r.id}${x.hit.r.agent ? '/' + x.hit.r.agent : ''}] "${x.x.u.slice(0, 58)}"`)); (A.amended || []).forEach(x => console.log(` -> AMEND step ${x.x.line} [${x.hit.r.id}] "${x.x.u.slice(0, 58)}"`)); } const prec = tp / (tp + fp || 1), rec = tp / (tp + fn || 1); console.log(`\nConfusion: TP=${tp} FP=${fp} FN=${fn} TN=${tn}`); - console.log(`Precision=${prec.toFixed(2)} Recall=${rec.toFixed(2)} Failures=${fail}`); + console.log(`Selected corpus only (${CORPUS.length} cases): Precision=${prec.toFixed(2)} Recall=${rec.toFixed(2)} Failures=${fail}`); + console.log('These selected cases are regression checks, not an estimate of real-world accuracy.'); console.log(fail === 0 ? "CORPUS GREEN" : "CORPUS RED — a label is failing; change the lexicon, not the label"); process.exit(fail === 0 ? 0 : 1); }