oh-my-opencode 5.1.47 → 5.1.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/refusal-rule.d.ts +7 -0
- package/dist/cli/index.js +1194 -752
- package/dist/cli/service-auth/accounts-gate.d.ts +11 -0
- package/dist/cli/service-auth/commands.d.ts +2 -4
- package/dist/cli/service-auth/index.d.ts +1 -1
- package/dist/cli/service-auth/keystore.d.ts +26 -2
- package/dist/cli/service-auth/protocol.d.ts +7 -1
- package/dist/cli/service-auth/session.d.ts +6 -0
- package/dist/cli/service-auth/signed-out-marker.d.ts +11 -0
- package/dist/cli-node/index.js +1194 -752
- package/dist/config/schema/hooks.d.ts +1 -0
- package/dist/create-hooks.d.ts +1 -0
- package/dist/features/boulder-state/storage.d.ts +1 -1
- package/dist/features/boulder-state/types.d.ts +1 -1
- package/dist/hooks/atlas/idle-continuation.d.ts +2 -1
- package/dist/hooks/atlas/types.d.ts +9 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/momus-review-persistence/hook.d.ts +19 -0
- package/dist/hooks/momus-review-persistence/index.d.ts +1 -0
- package/dist/hooks/momus-review-persistence/review-resolution.d.ts +20 -0
- package/dist/hooks/prometheus-md-only/constants.d.ts +2 -0
- package/dist/hooks/prometheus-md-only/fixtures/denial-log.d.ts +1 -0
- package/dist/hooks/prometheus-md-only/fixtures/guarded-hashline.d.ts +1 -0
- package/dist/hooks/prometheus-md-only/fixtures/invoke-before.d.ts +7 -0
- package/dist/hooks/prometheus-md-only/fixtures/opencode-patch-parser.d.ts +2 -0
- package/dist/hooks/prometheus-md-only/hook.d.ts +5 -1
- package/dist/hooks/prometheus-md-only/path-policy.d.ts +2 -9
- package/dist/hooks/prometheus-md-only/vendor/opencode-patch-parser.d.ts +22 -0
- package/dist/index.js +2322 -1045
- package/dist/plugin/hooks/create-core-hooks.d.ts +1 -0
- package/dist/plugin/hooks/create-tool-guard-hooks.d.ts +2 -1
- package/dist/shared/posthog-activity-state.d.ts +1 -0
- package/dist/shared/posthog.d.ts +1 -2
- package/dist/shared/resolve-file-write-path.d.ts +6 -0
- package/dist/skills/ast-grep/README.md +1 -1
- package/dist/skills/ast-grep/install.ps1 +5 -3
- package/dist/skills/ast-grep/install.sh +4 -5
- package/dist/skills/ast-grep/references/install.md +2 -2
- package/dist/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
- package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
- package/dist/skills/coding-agent-sessions/AGENTS.md +5 -4
- package/dist/skills/coding-agent-sessions/SKILL.md +11 -11
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +2 -2
- package/dist/skills/coding-agent-sessions/references/codex.md +4 -4
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
- package/dist/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
- package/dist/skills/frontend/ATTRIBUTION.md +1 -1
- package/dist/skills/frontend/SKILL.md +34 -12
- package/dist/skills/frontend/references/design/README.md +2 -2
- package/dist/skills/frontend/references/design/_INDEX.md +2 -1
- package/dist/skills/frontend/references/design/component-catalogs.md +14 -10
- package/dist/skills/frontend/references/design/design-system-architecture.md +19 -6
- package/dist/skills/frontend/references/design/grounding.md +29 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
- package/dist/skills/ultimate-browsing/SKILL.md +5 -4
- package/dist/skills/ultimate-browsing/engine/AGENTS.md +2 -2
- package/dist/skills/ultimate-browsing/engine/__main__.py +9 -6
- package/dist/skills/ultimate-browsing/engine/summary.py +1 -1
- package/dist/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/dist/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
- package/dist/skills/ulw-research/AGENTS.md +8 -4
- package/dist/skills/ulw-research/SKILL.md +7 -259
- package/dist/skills/ulw-research/references/deliverable-phase.md +68 -24
- package/dist/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
- package/dist/skills/ulw-research/references/fact-ledger.md +42 -8
- package/dist/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
- package/dist/skills/ulw-research/references/markdown-blocks.md +12 -0
- package/dist/skills/ulw-research/references/report-gates.md +14 -6
- package/dist/skills/ulw-research/references/research-collection.md +195 -0
- package/dist/skills/ulw-research/references/research-delivery.md +123 -0
- package/dist/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
- package/dist/skills/ulw-research/scripts/claim-kinds.test.ts +37 -2
- package/dist/skills/ulw-research/scripts/claim-prefix.test.ts +76 -0
- package/dist/skills/ulw-research/scripts/contracts-validation.test.ts +83 -0
- package/dist/skills/ulw-research/scripts/contracts.mjs +16 -15
- package/dist/skills/ulw-research/scripts/contracts.test.ts +6 -109
- package/dist/skills/ulw-research/scripts/conversion-altered.test.ts +154 -0
- package/dist/skills/ulw-research/scripts/conversion-originals.test.ts +297 -0
- package/dist/skills/ulw-research/scripts/conversion-probe-classes.test.ts +361 -0
- package/dist/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
- package/dist/skills/ulw-research/scripts/conversion-probe.test.ts +218 -0
- package/dist/skills/ulw-research/scripts/copy-returns-fidelity-policy.test.ts +156 -0
- package/dist/skills/ulw-research/scripts/copy-returns-polish.test.ts +10 -9
- package/dist/skills/ulw-research/scripts/css-hiding.mjs +158 -0
- package/dist/skills/ulw-research/scripts/css-lite.mjs +4 -2
- package/dist/skills/ulw-research/scripts/delivery-barrier-meaning.test.ts +186 -0
- package/dist/skills/ulw-research/scripts/delivery-barrier.test.ts +40 -87
- package/dist/skills/ulw-research/scripts/entities.mjs +13 -4
- package/dist/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
- package/dist/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
- package/dist/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
- package/dist/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
- package/dist/skills/ulw-research/scripts/fact-commands.mjs +40 -62
- package/dist/skills/ulw-research/scripts/fact-derive-2.test.ts +149 -0
- package/dist/skills/ulw-research/scripts/fact-derive.mjs +7 -2
- package/dist/skills/ulw-research/scripts/fact-derive.test.ts +7 -192
- package/dist/skills/ulw-research/scripts/fact-fill.mjs +9 -6
- package/dist/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
- package/dist/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +2 -1
- package/dist/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +2 -1
- package/dist/skills/ulw-research/scripts/fact-locate.mjs +15 -9
- package/dist/skills/ulw-research/scripts/fact-unit-dimensions-2.test.ts +149 -0
- package/dist/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +4 -168
- package/dist/skills/ulw-research/scripts/fact-unit-rules.test.ts +3 -229
- package/dist/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
- package/dist/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
- package/dist/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
- package/dist/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
- package/dist/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
- package/dist/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
- package/dist/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
- package/dist/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
- package/dist/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
- package/dist/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
- package/dist/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
- package/dist/skills/ulw-research/scripts/fidelity-values.test.ts +8 -29
- package/dist/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
- package/dist/skills/ulw-research/scripts/gates-static-headings.test.ts +17 -0
- package/dist/skills/ulw-research/scripts/gates-static.mjs +10 -1
- package/dist/skills/ulw-research/scripts/html-lite.mjs +6 -2
- package/dist/skills/ulw-research/scripts/html-markup.mjs +2 -2
- package/dist/skills/ulw-research/scripts/html-text-map.mjs +140 -0
- package/dist/skills/ulw-research/scripts/html-text-map.test.ts +148 -0
- package/dist/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
- package/dist/skills/ulw-research/scripts/md-lite-boundaries.test.ts +46 -0
- package/dist/skills/ulw-research/scripts/md-lite.mjs +1 -1
- package/dist/skills/ulw-research/scripts/number-grammar.mjs +33 -0
- package/dist/skills/ulw-research/scripts/number-grammar.test.ts +36 -0
- package/dist/skills/ulw-research/scripts/numerals.mjs +18 -7
- package/dist/skills/ulw-research/scripts/numerals.test.ts +3 -0
- package/dist/skills/ulw-research/scripts/outcome-start.mjs +66 -0
- package/dist/skills/ulw-research/scripts/outcome-start.test.ts +109 -0
- package/dist/skills/ulw-research/scripts/outcome.mjs +11 -22
- package/dist/skills/ulw-research/scripts/page-source-locator.test.ts +187 -0
- package/dist/skills/ulw-research/scripts/placeholder.mjs +18 -6
- package/dist/skills/ulw-research/scripts/polish-apply.mjs +3 -2
- package/dist/skills/ulw-research/scripts/polish-markup.test.ts +15 -1
- package/dist/skills/ulw-research/scripts/polish-partial.test.ts +42 -0
- package/dist/skills/ulw-research/scripts/raw-decode.mjs +110 -0
- package/dist/skills/ulw-research/scripts/raw-locator.mjs +47 -0
- package/dist/skills/ulw-research/scripts/raw-snapshot.test.ts +139 -0
- package/dist/skills/ulw-research/scripts/report-tools-2.test.ts +233 -0
- package/dist/skills/ulw-research/scripts/report-tools-3.test.ts +141 -0
- package/dist/skills/ulw-research/scripts/report-tools-4.test.ts +135 -0
- package/dist/skills/ulw-research/scripts/report-tools-5.test.ts +231 -0
- package/dist/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
- package/dist/skills/ulw-research/scripts/report-tools.mjs +7 -1
- package/dist/skills/ulw-research/scripts/report-tools.test.ts +6 -560
- package/dist/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
- package/dist/skills/ulw-research/scripts/source-commands.mjs +87 -29
- package/dist/skills/ulw-research/scripts/source-integrity.test.ts +243 -0
- package/dist/skills/ulw-research/scripts/source-refresh.mjs +82 -0
- package/dist/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
- package/dist/skills/ulw-research/scripts/source-snapshot.test.ts +7 -4
- package/dist/skills/ulw-research/scripts/source-view.mjs +89 -0
- package/dist/skills/ulw-research/scripts/sources-citation.mjs +203 -0
- package/dist/skills/ulw-research/scripts/sources-citation.test.ts +236 -0
- package/dist/skills/ulw-research/scripts/tests/contracts-support.ts +147 -0
- package/dist/skills/ulw-research/scripts/tests/delivery-barrier-session.ts +59 -0
- package/dist/skills/ulw-research/scripts/tests/derive-clock.ts +4 -0
- package/dist/skills/ulw-research/scripts/tests/fact-derive-support.ts +65 -0
- package/dist/skills/ulw-research/scripts/tests/fact-unit-dimensions-support.ts +41 -0
- package/dist/skills/ulw-research/scripts/tests/fact-unit-rules-support.ts +241 -0
- package/dist/skills/ulw-research/scripts/tests/fidelity-values-support.ts +30 -0
- package/dist/skills/ulw-research/scripts/tests/fixtures/conversion-probe.html +14 -0
- package/dist/skills/ulw-research/scripts/tests/fixtures/sources-shapes.html +20 -0
- package/dist/skills/ulw-research/scripts/tests/numeral-classes.ts +196 -0
- package/dist/skills/ulw-research/scripts/tests/report-tools-support.ts +182 -0
- package/dist/skills/ulw-research/scripts/tests/value-mode-support.ts +48 -0
- package/dist/skills/ulw-research/scripts/units.mjs +14 -3
- package/dist/skills/ulw-research/scripts/units.test.ts +10 -0
- package/dist/skills/ulw-research/scripts/value-mode-unit-classes.test.ts +255 -0
- package/dist/skills/ulw-research/scripts/value-mode-unit.test.ts +179 -0
- package/dist/skills/ulw-research/scripts/value-rules-cli.test.ts +157 -0
- package/dist/skills/ulw-research/scripts/value-rules-followups.test.ts +72 -0
- package/dist/skills/ulw-research/scripts/value-rules-priority.test.ts +80 -0
- package/dist/tools/delegate-task/executor-types.d.ts +1 -0
- package/dist/tools/delegate-task/sync-session-existence.d.ts +4 -0
- package/dist/tools/delegate-task/types.d.ts +1 -0
- package/dist/tools/skill/description-formatter.d.ts +2 -1
- package/dist/tools/skill/types.d.ts +6 -0
- package/dist/tui.js +131 -33
- package/package.json +18 -15
- package/packages/git-bash-mcp/package.json +1 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-contribute-bug-fix/SKILL.md +51 -55
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/SKILL.md +7 -7
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +2 -2
- package/packages/omo-codex/plugin/components/telemetry/README.md +2 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +52 -15
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +52 -19
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +2 -9
- package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -13
- package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +0 -2
- package/packages/omo-codex/plugin/components/telemetry/test/codex-hook-diagnostics.test.ts +0 -3
- package/packages/omo-codex/plugin/components/telemetry/test/codex-hook.test.ts +3 -8
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +3 -0
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +16 -16
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/shared/package.json +1 -1
- package/packages/omo-codex/plugin/skills/ast-grep/README.md +1 -1
- package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +5 -3
- package/packages/omo-codex/plugin/skills/ast-grep/install.sh +4 -5
- package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +2 -2
- package/packages/omo-codex/plugin/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
- package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +5 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +11 -11
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +2 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +4 -4
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +1 -1
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +34 -12
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +2 -2
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/component-catalogs.md +14 -10
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +19 -6
- package/packages/omo-codex/plugin/skills/frontend/references/design/grounding.md +29 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +51 -55
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +7 -7
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +5 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/__main__.py +9 -6
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/summary.py +1 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +3 -0
- package/packages/omo-codex/plugin/skills/ulw-research/AGENTS.md +8 -4
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +7 -259
- package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +68 -24
- package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
- package/packages/omo-codex/plugin/skills/ulw-research/references/fact-ledger.md +42 -8
- package/packages/omo-codex/plugin/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/references/markdown-blocks.md +12 -0
- package/packages/omo-codex/plugin/skills/ulw-research/references/report-gates.md +14 -6
- package/packages/omo-codex/plugin/skills/ulw-research/references/research-collection.md +195 -0
- package/packages/omo-codex/plugin/skills/ulw-research/references/research-delivery.md +123 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/contracts.mjs +16 -15
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-hiding.mjs +158 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/css-lite.mjs +4 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/entities.mjs +13 -4
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands.mjs +40 -62
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-derive.mjs +7 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-fill.mjs +9 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-locate.mjs +15 -9
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/gates-static.mjs +10 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-lite.mjs +6 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-markup.mjs +2 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/html-text-map.mjs +140 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/md-lite.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/number-grammar.mjs +33 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/numerals.mjs +18 -7
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome-start.mjs +66 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/outcome.mjs +11 -22
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/placeholder.mjs +18 -6
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/polish-apply.mjs +3 -2
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/raw-decode.mjs +110 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/raw-locator.mjs +47 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/report-tools.mjs +7 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-commands.mjs +87 -29
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-refresh.mjs +82 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/source-view.mjs +89 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/sources-citation.mjs +203 -0
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/units.mjs +14 -3
- package/packages/omo-codex/plugin/test/payload-equivalence.test.mjs +6 -4
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +4 -3
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +338 -237
- package/packages/prompts-core/prompts/ultrawork/codex.md +3 -0
- package/packages/shared-skills/skill-source-filter.mjs +6 -2
- package/packages/shared-skills/skills/ast-grep/README.md +1 -1
- package/packages/shared-skills/skills/ast-grep/install.ps1 +5 -3
- package/packages/shared-skills/skills/ast-grep/install.sh +4 -5
- package/packages/shared-skills/skills/ast-grep/references/install.md +2 -2
- package/packages/shared-skills/skills/ast-grep/scripts/ast_grep_helper.py +13 -3
- package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +5 -4
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +11 -11
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +2 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +4 -4
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +6 -3
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +1 -1
- package/packages/shared-skills/skills/frontend/SKILL.md +34 -12
- package/packages/shared-skills/skills/frontend/references/design/README.md +2 -2
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -1
- package/packages/shared-skills/skills/frontend/references/design/component-catalogs.md +14 -10
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +19 -6
- package/packages/shared-skills/skills/frontend/references/design/grounding.md +29 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +2 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +2 -0
- package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +5 -4
- package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +2 -2
- package/packages/shared-skills/skills/ultimate-browsing/engine/__main__.py +9 -6
- package/packages/shared-skills/skills/ultimate-browsing/engine/summary.py +1 -1
- package/packages/shared-skills/skills/ultimate-browsing/references/insane-search/README.md +4 -4
- package/packages/shared-skills/skills/ultimate-browsing/scripts/extract_cookies.py +4 -2
- package/packages/shared-skills/skills/ulw-research/AGENTS.md +8 -4
- package/packages/shared-skills/skills/ulw-research/SKILL.md +7 -259
- package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +68 -24
- package/packages/shared-skills/skills/ulw-research/references/fact-ledger-grammar.md +7 -3
- package/packages/shared-skills/skills/ulw-research/references/fact-ledger.md +42 -8
- package/packages/shared-skills/skills/ulw-research/references/fidelity-claim-kinds.md +1 -1
- package/packages/shared-skills/skills/ulw-research/references/markdown-blocks.md +12 -0
- package/packages/shared-skills/skills/ulw-research/references/report-gates.md +14 -6
- package/packages/shared-skills/skills/ulw-research/references/research-collection.md +195 -0
- package/packages/shared-skills/skills/ulw-research/references/research-delivery.md +123 -0
- package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.mjs +33 -5
- package/packages/shared-skills/skills/ulw-research/scripts/claim-kinds.test.ts +37 -2
- package/packages/shared-skills/skills/ulw-research/scripts/claim-prefix.test.ts +76 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts-validation.test.ts +83 -0
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.mjs +16 -15
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +6 -109
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-altered.test.ts +154 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-originals.test.ts +297 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe-classes.test.ts +361 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe.mjs +229 -0
- package/packages/shared-skills/skills/ulw-research/scripts/conversion-probe.test.ts +218 -0
- package/packages/shared-skills/skills/ulw-research/scripts/copy-returns-fidelity-policy.test.ts +156 -0
- package/packages/shared-skills/skills/ulw-research/scripts/copy-returns-polish.test.ts +10 -9
- package/packages/shared-skills/skills/ulw-research/scripts/css-hiding.mjs +158 -0
- package/packages/shared-skills/skills/ulw-research/scripts/css-lite.mjs +4 -2
- package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier-meaning.test.ts +186 -0
- package/packages/shared-skills/skills/ulw-research/scripts/delivery-barrier.test.ts +40 -87
- package/packages/shared-skills/skills/ulw-research/scripts/entities.mjs +13 -4
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-fill.mjs +96 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-meaning.mjs +26 -30
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-polish.mjs +46 -19
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-verify.mjs +37 -6
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands.mjs +40 -62
- package/packages/shared-skills/skills/ulw-research/scripts/fact-derive-2.test.ts +149 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.mjs +7 -2
- package/packages/shared-skills/skills/ulw-research/scripts/fact-derive.test.ts +7 -192
- package/packages/shared-skills/skills/ulw-research/scripts/fact-fill.mjs +9 -6
- package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.mjs +6 -7
- package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-kinds.test.ts +2 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fact-ledger-legacy.test.ts +2 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fact-locate.mjs +15 -9
- package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions-2.test.ts +149 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-dimensions.test.ts +4 -168
- package/packages/shared-skills/skills/ulw-research/scripts/fact-unit-rules.test.ts +3 -229
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-claims.mjs +4 -3
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-csv.mjs +32 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-lexicon.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-originals.mjs +161 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-policy.mjs +183 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-records.mjs +81 -14
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-snapshot-readability.mjs +49 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-sources.mjs +76 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-trace.mjs +25 -11
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-value-unit.mjs +202 -0
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.mjs +40 -39
- package/packages/shared-skills/skills/ulw-research/scripts/fidelity-values.test.ts +8 -29
- package/packages/shared-skills/skills/ulw-research/scripts/gates-fidelity.mjs +8 -6
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static-headings.test.ts +17 -0
- package/packages/shared-skills/skills/ulw-research/scripts/gates-static.mjs +10 -1
- package/packages/shared-skills/skills/ulw-research/scripts/html-lite.mjs +6 -2
- package/packages/shared-skills/skills/ulw-research/scripts/html-markup.mjs +2 -2
- package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.mjs +140 -0
- package/packages/shared-skills/skills/ulw-research/scripts/html-text-map.test.ts +148 -0
- package/packages/shared-skills/skills/ulw-research/scripts/markdown-closers.mjs +126 -0
- package/packages/shared-skills/skills/ulw-research/scripts/md-lite-boundaries.test.ts +46 -0
- package/packages/shared-skills/skills/ulw-research/scripts/md-lite.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.mjs +33 -0
- package/packages/shared-skills/skills/ulw-research/scripts/number-grammar.test.ts +36 -0
- package/packages/shared-skills/skills/ulw-research/scripts/numerals.mjs +18 -7
- package/packages/shared-skills/skills/ulw-research/scripts/numerals.test.ts +3 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.mjs +66 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome-start.test.ts +109 -0
- package/packages/shared-skills/skills/ulw-research/scripts/outcome.mjs +11 -22
- package/packages/shared-skills/skills/ulw-research/scripts/page-source-locator.test.ts +187 -0
- package/packages/shared-skills/skills/ulw-research/scripts/placeholder.mjs +18 -6
- package/packages/shared-skills/skills/ulw-research/scripts/polish-apply.mjs +3 -2
- package/packages/shared-skills/skills/ulw-research/scripts/polish-markup.test.ts +15 -1
- package/packages/shared-skills/skills/ulw-research/scripts/polish-partial.test.ts +42 -0
- package/packages/shared-skills/skills/ulw-research/scripts/raw-decode.mjs +110 -0
- package/packages/shared-skills/skills/ulw-research/scripts/raw-locator.mjs +47 -0
- package/packages/shared-skills/skills/ulw-research/scripts/raw-snapshot.test.ts +139 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-2.test.ts +233 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-3.test.ts +141 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-4.test.ts +135 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-5.test.ts +231 -0
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools-commands.mjs +1 -1
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools.mjs +7 -1
- package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +6 -560
- package/packages/shared-skills/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
- package/packages/shared-skills/skills/ulw-research/scripts/source-commands.mjs +87 -29
- package/packages/shared-skills/skills/ulw-research/scripts/source-integrity.test.ts +243 -0
- package/packages/shared-skills/skills/ulw-research/scripts/source-refresh.mjs +82 -0
- package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.mjs +73 -69
- package/packages/shared-skills/skills/ulw-research/scripts/source-snapshot.test.ts +7 -4
- package/packages/shared-skills/skills/ulw-research/scripts/source-view.mjs +89 -0
- package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.mjs +203 -0
- package/packages/shared-skills/skills/ulw-research/scripts/sources-citation.test.ts +236 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/contracts-support.ts +147 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/delivery-barrier-session.ts +59 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/derive-clock.ts +4 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-derive-support.ts +65 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-dimensions-support.ts +41 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fact-unit-rules-support.ts +241 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fidelity-values-support.ts +30 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/conversion-probe.html +14 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/fixtures/sources-shapes.html +20 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/numeral-classes.ts +196 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/report-tools-support.ts +182 -0
- package/packages/shared-skills/skills/ulw-research/scripts/tests/value-mode-support.ts +48 -0
- package/packages/shared-skills/skills/ulw-research/scripts/units.mjs +14 -3
- package/packages/shared-skills/skills/ulw-research/scripts/units.test.ts +10 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit-classes.test.ts +255 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-mode-unit.test.ts +179 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-rules-cli.test.ts +157 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-rules-followups.test.ts +72 -0
- package/packages/shared-skills/skills/ulw-research/scripts/value-rules-priority.test.ts +80 -0
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/amp_redirect_stub.html +0 -7
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/search_interstitial.html +0 -19
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_available.json +0 -1
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/fixtures/wayback_snapshot.html +0 -1128
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_fetch_chain.py +0 -77
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_stealth.py +0 -86
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_playwright_templates.py +0 -279
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate.py +0 -252
- package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/tests/test_surrogate_validators.py +0 -78
|
@@ -1,25 +1,28 @@
|
|
|
1
1
|
// fact-commands-meaning.mjs - `fact pairs` and `fact meaning-check`, the script half of the
|
|
2
2
|
// separate-session meaning verifier. fact pairs writes the (source, report sentence) pairs a
|
|
3
|
-
// reader lane gets and nothing else (with --changed-since, only the pairs whose sentence
|
|
4
|
-
//
|
|
3
|
+
// reader lane gets and nothing else (with --changed-since, only the pairs whose sentence changed
|
|
4
|
+
// since the pre-polish fill map's artifact, or all when those bytes are gone); it honours the brief's `meaning check` field and writes
|
|
5
5
|
// `{ skipped: true }` when it is off. fact meaning-check ingests the readers' verdict files
|
|
6
|
-
// (meaning-check.mjs), writes
|
|
6
|
+
// (meaning-check.mjs), writes the meaning record of one edition (fidelity-meaning-defects.<format>.json
|
|
7
|
+
// with --edition, else the legacy fidelity-meaning-defects.json; a fidelity record bound to the pairs'
|
|
7
8
|
// artifact_sha256 and report, through writeFidelityRecord), and records the run in
|
|
8
9
|
// fidelity-calibration.jsonl: a header with the promotion criterion on first write, then per run
|
|
9
10
|
// one run line plus one line per flagged pair. The run id hashes the inputs only, so a rerun or a
|
|
10
11
|
// --dispute rerun of the same inputs replaces that run's lines in place (disputes carry forward)
|
|
11
|
-
// instead of counting a second run.
|
|
12
|
+
// instead of counting a second run. Both refuse an unlocked brief (fidelity_interview_incomplete) before
|
|
13
|
+
// reading anything else. Neither command calls a model or the network.
|
|
12
14
|
|
|
13
15
|
import { existsSync, readFileSync } from "node:fs"
|
|
14
16
|
import { dirname, join, resolve } from "node:path"
|
|
15
17
|
|
|
16
18
|
import { CliError, parseArgs, readJsonFile, sha256Of, writeJsonAtomic, writeTextAtomic } from "./cli-support.mjs"
|
|
17
|
-
import { countDefects } from "./contracts.mjs"
|
|
19
|
+
import { countDefects, DELIVERABLE_FORMATS } from "./contracts.mjs"
|
|
18
20
|
import { ledgerFrom, markdownAsHtml, readEdition, sessionOf } from "./fact-commands-verify.mjs"
|
|
19
21
|
import { pairsChangedSince } from "./fact-commands-polish.mjs"
|
|
20
22
|
import { extractPairs, PAIR_KINDS } from "./fact-pairs.mjs"
|
|
21
|
-
import { FIDELITY_INCOMPLETE
|
|
22
|
-
import {
|
|
23
|
+
import { FIDELITY_INCOMPLETE } from "./fidelity-brief.mjs"
|
|
24
|
+
import { briefPathOf, lockedBrief, meaningCheckEnabled } from "./fidelity-policy.mjs"
|
|
25
|
+
import { MEANING_RECORD, meaningRecordName, writeFidelityRecord } from "./fidelity-records.mjs"
|
|
23
26
|
import { blocksDelivery } from "./gates-fidelity.mjs"
|
|
24
27
|
import { ingestVerdicts, unverifiedDefects, VERDICT_SCHEMA } from "./meaning-check.mjs"
|
|
25
28
|
|
|
@@ -36,25 +39,15 @@ const inSession = (session, name, flag) => {
|
|
|
36
39
|
return join(session, name)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
|
-
function briefState(flags, session) {
|
|
40
|
-
const path = flags.brief ?? inSession(session, "brief.md", "--brief")
|
|
41
|
-
const lock = requireLockedBrief(path)
|
|
42
|
-
if (lock.exitCode === 2) throw new CliError(`${path}: malformed ## Fidelity block: ${lock.errors.join("; ")}`)
|
|
43
|
-
return { path, locked: lock.locked, off: !meaningCheckEnabled(lock.parsed) }
|
|
44
|
-
}
|
|
45
|
-
|
|
46
42
|
function runPairs(args) {
|
|
47
43
|
const [report] = args.positionals
|
|
48
44
|
const { flags } = args
|
|
49
45
|
if (!report) throw new CliError("usage: fact pairs <report> [--format html|md] [--ledger F] [--claims claims.json] [--changed-since <fill-map.json>] [--brief brief.md] [--out pairs.json]")
|
|
50
46
|
const session = sessionOf(flags)
|
|
51
47
|
const out = resolve(flags.out ?? inSession(session, PAIRS_FILE, "--out"))
|
|
52
|
-
const
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
return { json, summary: `fact pairs: ${json.message}`, exitCode: 1 }
|
|
56
|
-
}
|
|
57
|
-
if (brief.off) {
|
|
48
|
+
const { parsed, refusal } = lockedBrief("fact pairs", flags)
|
|
49
|
+
if (refusal) return refusal
|
|
50
|
+
if (!meaningCheckEnabled(parsed)) {
|
|
58
51
|
const record = { schemaVersion: 1, skipped: true, reason: "meaning check: off", pairs: [] }
|
|
59
52
|
writeJsonAtomic(out, record)
|
|
60
53
|
return { json: { command: "fact pairs", status: "skipped", exitCode: 0, data: { out, ...record } }, summary: "fact pairs: skipped (meaning check: off)", exitCode: 0 }
|
|
@@ -65,10 +58,12 @@ function runPairs(args) {
|
|
|
65
58
|
const ledger = ledgerFrom(flags, session)
|
|
66
59
|
const html = edition.format === "md" ? markdownAsHtml(edition.text, edition.entries, ledger).html : edition.text
|
|
67
60
|
const all = extractPairs(html, ledger, claims)
|
|
68
|
-
const
|
|
61
|
+
const since = flags["changed-since"] === undefined ? null : pairsChangedSince(all, flags["changed-since"], ledger, claims)
|
|
62
|
+
const pairs = since?.pairs ?? all
|
|
69
63
|
const counts = { total: pairs.length, force_strong: pairs.filter((pair) => pair.force_strong).length }
|
|
70
64
|
for (const kind of PAIR_KINDS) counts[kind] = pairs.filter((pair) => pair.kind === kind).length
|
|
71
|
-
const
|
|
65
|
+
const changed = since === null ? {} : { changed_since: { fill_map: since.fill_map, narrowed: since.narrowed } }
|
|
66
|
+
const record = { schemaVersion: 1, skipped: false, report: resolve(report), format: edition.format, artifact_sha256: sha256Of(edition.text), pairs_sha256: sha256Of(JSON.stringify(pairs)), counts, ...changed, verdict_schema: VERDICT_SCHEMA, pairs }
|
|
72
67
|
writeJsonAtomic(out, record)
|
|
73
68
|
const summary = `fact pairs: ${counts.total} pair(s), ${counts.force_strong} routed to the strong reader`
|
|
74
69
|
return { json: { command: "fact pairs", status: "pass", exitCode: 0, data: { out, ...record, pairs: undefined } }, summary, exitCode: 0 }
|
|
@@ -125,23 +120,24 @@ function recordCalibration(path, lines, runId, pairsSha) {
|
|
|
125
120
|
}
|
|
126
121
|
|
|
127
122
|
/** A `{ skipped: true }` pairs file is accepted only when the locked brief turns the meaning check off. */
|
|
128
|
-
function skippedRefusal(flags,
|
|
129
|
-
|
|
130
|
-
if (!brief.locked) return { error: FIDELITY_INCOMPLETE, message: `${brief.path} has no locked ## Fidelity block, so a skipped meaning check cannot be accepted` }
|
|
131
|
-
if (!brief.off) return { error: "meaning_check_required", message: `${flags.pairs} says skipped but ${brief.path} has meaning check on; rerun fact pairs` }
|
|
123
|
+
function skippedRefusal(flags, parsed) {
|
|
124
|
+
if (meaningCheckEnabled(parsed)) return { error: "meaning_check_required", message: `${flags.pairs} says skipped but ${briefPathOf(flags)} has meaning check on; rerun fact pairs` }
|
|
132
125
|
return null
|
|
133
126
|
}
|
|
134
127
|
|
|
135
128
|
function runMeaningCheck(args) {
|
|
136
129
|
const { flags } = args
|
|
137
|
-
const usage = "usage: fact meaning-check --pairs pairs.json --verdicts cheap.json [--verdicts strong.json] [--dispute P<n> --reason TEXT] [--run-id ID] [--calibration F] [--out F]"
|
|
130
|
+
const usage = "usage: fact meaning-check --pairs pairs.json --verdicts cheap.json [--verdicts strong.json] [--dispute P<n> --reason TEXT] [--run-id ID] [--calibration F] [--brief brief.md] [--edition FORMAT] [--out F]"
|
|
138
131
|
if (flags.pairs === undefined || !Array.isArray(flags.verdicts)) throw new CliError(usage)
|
|
132
|
+
if (flags.edition !== undefined && !DELIVERABLE_FORMATS.includes(flags.edition)) throw new CliError(`--edition must be a deliverable format (${DELIVERABLE_FORMATS.join(", ")}), got ${flags.edition}`)
|
|
139
133
|
const session = sessionOf(flags)
|
|
134
|
+
const { parsed, refusal } = lockedBrief("fact meaning-check", flags)
|
|
135
|
+
if (refusal) return { ...refusal, json: { ...refusal.json, error: FIDELITY_INCOMPLETE } }
|
|
140
136
|
const pairsText = readFileSync(flags.pairs, "utf8")
|
|
141
137
|
const pairsDoc = readJsonFile(flags.pairs)
|
|
142
138
|
if (pairsDoc?.skipped === true) {
|
|
143
|
-
const
|
|
144
|
-
if (
|
|
139
|
+
const skipped = skippedRefusal(flags, parsed)
|
|
140
|
+
if (skipped !== null) return { json: { command: "fact meaning-check", status: "fail", exitCode: 1, ...skipped }, summary: `fact meaning-check: ${skipped.message}`, exitCode: 1 }
|
|
145
141
|
return { json: { command: "fact meaning-check", status: "skipped", exitCode: 0, defects: [] }, summary: JSON.stringify({ command: "fact meaning-check", status: "skipped" }), exitCode: 0 }
|
|
146
142
|
}
|
|
147
143
|
if (typeof pairsDoc?.artifact_sha256 !== "string" || typeof pairsDoc.report !== "string") throw new CliError(`${flags.pairs} names no artifact_sha256 and report, so the meaning record cannot be bound to an edition; rerun fact pairs`)
|
|
@@ -154,7 +150,7 @@ function runMeaningCheck(args) {
|
|
|
154
150
|
} catch (error) {
|
|
155
151
|
throw new CliError(`invalid verdict input: ${error.message}`)
|
|
156
152
|
}
|
|
157
|
-
const out = resolve(flags.out ?? inSession(session, MEANING_RECORD, "--out"))
|
|
153
|
+
const out = resolve(flags.out ?? inSession(session, flags.edition === undefined ? MEANING_RECORD : meaningRecordName(flags.edition), "--out"))
|
|
158
154
|
const calibration = resolve(flags.calibration ?? join(session ?? dirname(out), CALIBRATION_FILE))
|
|
159
155
|
const runId = flags["run-id"] ?? sha256Of([pairsText, ...verdictTexts].join("\0")).slice(0, 16)
|
|
160
156
|
const pairsSha = pairsDoc.pairs_sha256 ?? sha256Of(pairsText)
|
|
@@ -6,19 +6,26 @@
|
|
|
6
6
|
// rejected (major) or unlocated (minor) edit leaves its region unchanged and is listed with its
|
|
7
7
|
// index and reason so the orchestrator can re-send it; every rejection reason is printed verbatim, one
|
|
8
8
|
// line per rejected edit (index and the first 60 characters of its before), in the summary and in
|
|
9
|
-
// data.rejected_reasons. It exits 0 whenever it wrote the output.
|
|
9
|
+
// data.rejected_reasons. It exits 0 whenever it wrote the output; json.applied is false when
|
|
10
|
+
// any edit was rejected or unlocated, independently of data.applied's accepted-edit count.
|
|
11
|
+
// polish-apply never rewrites a fill map: it checks that the edition's map (fillMapOf) records the
|
|
12
|
+
// input's bytes, refusing otherwise, and writes `<out>.polished.fill-map.json` beside the output
|
|
13
|
+
// (artifact = the polished file, its hash, and polishedFrom = the fill map's path and sha256).
|
|
10
14
|
// polish-diff is the whole-document backstop (polish-diff.mjs) between the pre-polish artifact
|
|
11
|
-
// and any later copy; it exits 1 on a blocker. pairsChangedSince
|
|
12
|
-
//
|
|
13
|
-
// meaning readers re-check exactly what
|
|
15
|
+
// and any later copy; it exits 1 on a blocker. pairsChangedSince always reads the pre-polish fill
|
|
16
|
+
// map (following a polished map's polishedFrom) and keeps only the pairs whose sentence text
|
|
17
|
+
// (normalized) is not in the artifact it names, so the meaning readers re-check exactly what
|
|
18
|
+
// changed; when that artifact no longer hashes to the map (polished in place, or edited) nothing
|
|
19
|
+
// can be ruled out and every pair is kept. No model, no network.
|
|
14
20
|
|
|
15
21
|
import { existsSync, readFileSync } from "node:fs"
|
|
16
22
|
import { join, resolve } from "node:path"
|
|
17
23
|
|
|
18
24
|
import { CliError, parseArgs, readJsonFile, sha256Of, writeJsonAtomic, writeTextAtomic } from "./cli-support.mjs"
|
|
19
25
|
import { countDefects, DEFECT_CODES } from "./contracts.mjs"
|
|
20
|
-
import { editionFormatOf, ledgerFrom, markdownAsHtml, sessionOf } from "./fact-commands-verify.mjs"
|
|
26
|
+
import { editionFormatOf, fillMapOf, ledgerFrom, markdownAsHtml, sessionOf } from "./fact-commands-verify.mjs"
|
|
21
27
|
import { extractPairs } from "./fact-pairs.mjs"
|
|
28
|
+
import { lockedBrief } from "./fidelity-policy.mjs"
|
|
22
29
|
import { applyEdits, POLISH_EDIT_FIELDS, validatePolishEdits } from "./polish-apply.mjs"
|
|
23
30
|
import { diffPolish } from "./polish-diff.mjs"
|
|
24
31
|
import { normalizeText } from "./text-normalize.mjs"
|
|
@@ -57,8 +64,10 @@ const rejectionLine = (entry, edit) => ` rejected edit ${entry.index} ("${befor
|
|
|
57
64
|
function runPolishApply(args) {
|
|
58
65
|
const [report] = args.positionals
|
|
59
66
|
const { flags } = args
|
|
60
|
-
if (!report || flags.edits === undefined || flags.out === undefined) throw new CliError("usage: fact polish-apply <report.html> --edits polish-edits.json --out <report.polished.html> [--ledger F] [--session-dir D]")
|
|
67
|
+
if (!report || flags.edits === undefined || flags.out === undefined) throw new CliError("usage: fact polish-apply <report.html> --edits polish-edits.json --out <report.polished.html> [--fill-map F] [--ledger F] [--brief brief.md] [--session-dir D]")
|
|
61
68
|
if (editionFormatOf(report, flags.format) === "md") throw new CliError("fact polish-apply takes the filled HTML edition; polish a Markdown edition through its HTML source")
|
|
69
|
+
const { refusal } = lockedBrief("fact polish-apply", flags)
|
|
70
|
+
if (refusal) return refusal
|
|
62
71
|
const html = readText(report)
|
|
63
72
|
const editsText = readText(flags.edits)
|
|
64
73
|
const edits = readJsonFile(flags.edits)
|
|
@@ -68,18 +77,25 @@ function runPolishApply(args) {
|
|
|
68
77
|
throw new CliError(`${flags.edits} must be an array of {${Object.keys(POLISH_EDIT_FIELDS).join(", ")}} objects: ${error.message}`)
|
|
69
78
|
}
|
|
70
79
|
const result = applyEdits(html, edits, ledgerFrom(flags))
|
|
80
|
+
const mapPath = fillMapOf(report, html, flags["fill-map"])
|
|
81
|
+
const map = mapPath === null ? null : readJsonFile(mapPath)
|
|
82
|
+
if (map !== null && map.artifact_sha256 !== sha256Of(html)) throw new CliError(`${mapPath} does not record the bytes of ${report} (artifact_sha256 differs); refusing to carry its brief binding to the polished edition`)
|
|
83
|
+
const polishedFrom = map?.polishedFrom ?? (map && { map: resolve(mapPath), sha256: sha256Of(readText(mapPath)) })
|
|
71
84
|
writeTextAtomic(flags.out, result.out)
|
|
85
|
+
if (map) writeJsonAtomic(`${resolve(flags.out)}.polished.fill-map.json`, { ...map, artifact: resolve(flags.out), artifact_sha256: sha256Of(result.out), polishedFrom })
|
|
72
86
|
const defects = [...result.rejected, ...result.unlocated].sort((a, b) => a.index - b.index).map(withSeverity)
|
|
73
87
|
const counts = { applied: result.applied.length, rejected: result.rejected.length, unlocated: result.unlocated.length }
|
|
74
88
|
const data = { out: resolve(flags.out), ...counts, applied_indexes: result.applied, input_sha256: sha256Of(html), edits_sha256: sha256Of(editsText), out_sha256: sha256Of(result.out) }
|
|
75
89
|
const rejected_reasons = result.rejected.map((entry) => rejectionLine(entry, edits[entry.index]))
|
|
76
90
|
const summary = [`fact polish-apply: ${counts.applied} applied, ${counts.rejected} rejected, ${counts.unlocated} unlocated of ${edits.length} edit(s)`, ...rejected_reasons].join("\n")
|
|
77
|
-
return { json: { command: "fact polish-apply", status: "pass", exitCode: 0, defects, data: { ...data, rejected_reasons } }, summary, exitCode: 0 }
|
|
91
|
+
return { json: { command: "fact polish-apply", status: "pass", exitCode: 0, applied: counts.rejected === 0 && counts.unlocated === 0, defects, data: { ...data, rejected_reasons } }, summary, exitCode: 0 }
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
function runPolishDiff(args) {
|
|
81
95
|
const { flags } = args
|
|
82
|
-
if (flags.before === undefined || flags.after === undefined) throw new CliError("usage: fact polish-diff --before <pre-polish.html> --after <polished.html> [--ledger F] [--out polish-defects.json] [--session-dir D]")
|
|
96
|
+
if (flags.before === undefined || flags.after === undefined) throw new CliError("usage: fact polish-diff --before <pre-polish.html> --after <polished.html> [--ledger F] [--out polish-defects.json] [--brief brief.md] [--session-dir D]")
|
|
97
|
+
const { refusal } = lockedBrief("fact polish-diff", flags)
|
|
98
|
+
if (refusal) return refusal
|
|
83
99
|
const after = readText(flags.after)
|
|
84
100
|
const defects = diffPolish(readText(flags.before), after, ledgerFrom(flags)).map((defect) => ({ ...defect, hint: DEFECT_CODES[defect.code]?.hint ?? null }))
|
|
85
101
|
const counts = countDefects(defects)
|
|
@@ -95,29 +111,40 @@ function runPolishDiff(args) {
|
|
|
95
111
|
|
|
96
112
|
const pairKey = (pair) => [pair.kind, pair.sentence_key, pair.claim_id ?? "", normalizeText(pair.sentence)].join("\u0000")
|
|
97
113
|
|
|
114
|
+
/** The pre-polish fill map behind --changed-since: a polished map leads to it through polishedFrom, whose sha256 it must still match. */
|
|
115
|
+
function prePolishMap(mapPath) {
|
|
116
|
+
const given = readJsonFile(mapPath)
|
|
117
|
+
if (given.polishedFrom === undefined) return { path: resolve(mapPath), map: given }
|
|
118
|
+
const { map: path, sha256 } = given.polishedFrom
|
|
119
|
+
if (typeof path !== "string" || sha256Of(readText(path)) !== sha256) throw new CliError(`${path} changed after polish wrote ${mapPath}; --changed-since needs the pre-polish fill map it names`)
|
|
120
|
+
return { path, map: readJsonFile(path) }
|
|
121
|
+
}
|
|
122
|
+
|
|
98
123
|
/**
|
|
99
|
-
* The pairs whose sentence text changed since the pre-polish artifact
|
|
100
|
-
* kept unless the same (kind, sentence key, normalized sentence) occurs in that artifact.
|
|
101
|
-
*
|
|
102
|
-
*
|
|
124
|
+
* The pairs whose sentence text changed since the pre-polish artifact the fill map names: a pair is
|
|
125
|
+
* kept unless the same (kind, sentence key, normalized sentence) occurs in that artifact. Only bytes
|
|
126
|
+
* that still hash to the map's `artifact_sha256` narrow the set; otherwise (the report was polished
|
|
127
|
+
* in place, or edited) every pair is kept, so nothing changed escapes the meaning re-check.
|
|
103
128
|
* @param {object[]} pairs extractPairs output on the polished edition
|
|
104
|
-
* @param {string} mapPath
|
|
129
|
+
* @param {string} mapPath fact fill's `<out>.fill-map.json`, or polish-apply's `<out>.polished.fill-map.json`
|
|
130
|
+
* @returns {{ pairs: object[], fill_map: string, narrowed: boolean }}
|
|
105
131
|
*/
|
|
106
132
|
export function pairsChangedSince(pairs, mapPath, ledger, claims) {
|
|
107
|
-
const map =
|
|
108
|
-
if (typeof map.artifact !== "string"
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (sha256Of(text) !== map.artifact_sha256)
|
|
133
|
+
const { path, map } = prePolishMap(mapPath)
|
|
134
|
+
if (typeof map.artifact !== "string") throw new CliError(`${path} names no pre-polish artifact`)
|
|
135
|
+
if (typeof map.artifact_sha256 !== "string") throw new CliError(`${path} fill map has no artifact_sha256; --changed-since needs the pre-polish hash`)
|
|
136
|
+
const text = existsSync(map.artifact) ? readText(map.artifact) : null
|
|
137
|
+
if (text === null || sha256Of(text) !== map.artifact_sha256) return { pairs, fill_map: path, narrowed: false }
|
|
112
138
|
const html = map.format === "md" ? markdownAsHtml(text, map.entries, ledger).html : text
|
|
113
139
|
const before = new Map()
|
|
114
140
|
for (const pair of extractPairs(html, ledger, claims)) before.set(pairKey(pair), (before.get(pairKey(pair)) ?? 0) + 1)
|
|
115
|
-
|
|
141
|
+
const kept = pairs.filter((pair) => {
|
|
116
142
|
const left = before.get(pairKey(pair)) ?? 0
|
|
117
143
|
if (left === 0) return true
|
|
118
144
|
before.set(pairKey(pair), left - 1)
|
|
119
145
|
return false
|
|
120
146
|
})
|
|
147
|
+
return { pairs: kept, fill_map: path, narrowed: true }
|
|
121
148
|
}
|
|
122
149
|
|
|
123
150
|
/** @param {string[]} argv the arguments after `fact polish-apply` or `fact polish-diff` */
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
// escaped HTML projection (same line numbers) and checked with its fill map, which is the only
|
|
9
9
|
// record of where its values sit; LaTeX is verified through its Markdown source.
|
|
10
10
|
//
|
|
11
|
+
// The locked brief is re-judged here, not only at fill: every edition (HTML or Markdown) needs its
|
|
12
|
+
// fill map (fillMapOf: --fill-map, else whichever of `<report>.fill-map.json` and the
|
|
13
|
+
// `<report>.polished.fill-map.json` polish-apply writes records the edition's bytes), and that map
|
|
14
|
+
// must carry the current brief's brief_sha256; no map, or another hash, is brief_changed. policyErrors
|
|
15
|
+
// re-runs over every data-fact the edition carries, so an edition that violates the current
|
|
16
|
+
// derived-numbers or source-floor rule fails here too.
|
|
17
|
+
//
|
|
11
18
|
// The delivery barrier that reads these records (and every other fidelity record) is
|
|
12
19
|
// fidelity-records.mjs.
|
|
13
20
|
|
|
@@ -19,6 +26,7 @@ import { countDefects } from "./contracts.mjs"
|
|
|
19
26
|
import { recompute } from "./fact-derive.mjs"
|
|
20
27
|
import { readLedger } from "./fact-ledger.mjs"
|
|
21
28
|
import { validateLedger } from "./fact-ledger-schema.mjs"
|
|
29
|
+
import { briefBindingErrors, fillPolicy, lockedBrief, policyErrors } from "./fidelity-policy.mjs"
|
|
22
30
|
import { FIDELITY_RECORD, writeFidelityRecord } from "./fidelity-records.mjs"
|
|
23
31
|
import { blocksDelivery, checkFidelity } from "./gates-fidelity.mjs"
|
|
24
32
|
import { parseMarkdown } from "./md-lite.mjs"
|
|
@@ -60,8 +68,8 @@ function entryHtml(text, entry, rows) {
|
|
|
60
68
|
if (entry.translates) return `<span data-translates="${escapeHtml(entry.translates)}">${projectMarkdownInline(body.replace(/^<!--[\s\S]*?-->\s*/u, ""))}</span>`
|
|
61
69
|
if (!row) return `<data data-fact="${escapeHtml(entry.fact_id)}">${escapeHtml(body)}</data>`
|
|
62
70
|
const quoted = row.kind === "quote" ? parseRenderedQuote(body) : null
|
|
63
|
-
if (quoted) return renderQuote(row, entry.selector ?? "full", quoted.text, "html")
|
|
64
|
-
return row.kind === "quote" ? null : renderValueHtml(row, body)
|
|
71
|
+
if (quoted) return renderQuote(row, entry.selector ?? "full", quoted.text, "html", entry.claimKind)
|
|
72
|
+
return row.kind === "quote" ? null : renderValueHtml(row, body, { mode: entry.mode, claimKind: entry.claimKind ?? null })
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
/** [from, to) of the filled text as HTML, each intact fill-map entry rebuilt as its fill element. */
|
|
@@ -143,6 +151,17 @@ const MARKDOWN_EXTENSION = /\.(md|markdown)$/iu
|
|
|
143
151
|
/** The edition format: the explicit flag, else md for a .md or .markdown path (any case), else html. */
|
|
144
152
|
export const editionFormatOf = (path, flag) => flag ?? (MARKDOWN_EXTENSION.test(path) ? "md" : "html")
|
|
145
153
|
|
|
154
|
+
/**
|
|
155
|
+
* An edition's fill map path: --fill-map, else whichever of fact fill's `<report>.fill-map.json` and
|
|
156
|
+
* polish-apply's `<report>.polished.fill-map.json` records these bytes as its artifact_sha256, else the
|
|
157
|
+
* first of them that exists; null when neither exists.
|
|
158
|
+
*/
|
|
159
|
+
export function fillMapOf(report, text, flag) {
|
|
160
|
+
if (flag !== undefined) return flag
|
|
161
|
+
const found = [`${report}.fill-map.json`, `${report}.polished.fill-map.json`].filter((path) => existsSync(path))
|
|
162
|
+
return found.find((path) => readJsonFile(path).artifact_sha256 === sha256Of(text)) ?? found[0] ?? null
|
|
163
|
+
}
|
|
164
|
+
|
|
146
165
|
/** The report's format (from --format or its extension) and, for Markdown, its fill map entries. */
|
|
147
166
|
export function readEdition(report, flags) {
|
|
148
167
|
const format = editionFormatOf(report, flags.format)
|
|
@@ -159,25 +178,37 @@ export function runFactVerify(args) {
|
|
|
159
178
|
const [report] = args.positionals
|
|
160
179
|
const { flags } = args
|
|
161
180
|
if (!report) throw new CliError("usage: fact verify <report> [--format html|md] [--sources D] [--claims claims.json] [--fill-map F] [--brief brief.md] [--out fidelity-defects.json]")
|
|
162
|
-
const edition = readEdition(report, flags)
|
|
163
181
|
const sessionDir = sessionDirOf(flags)
|
|
182
|
+
const { parsed, refusal } = lockedBrief("fact verify", flags)
|
|
183
|
+
if (refusal) return refusal
|
|
184
|
+
const policy = fillPolicy(parsed)
|
|
185
|
+
const edition = readEdition(report, flags)
|
|
164
186
|
const claimsPath = flags.claims ?? join(sessionDir, "claims.json")
|
|
165
187
|
const briefPath = flags.brief ?? join(sessionDir, "brief.md")
|
|
166
188
|
const ledger = readLedger(sessionDir)
|
|
167
189
|
const projected = edition.format === "md" ? markdownAsHtml(edition.text, edition.entries, ledger) : null
|
|
190
|
+
// The entries whose element is in the checked HTML: an HTML edition's own map, or the projection's intact entries.
|
|
191
|
+
const ownMap = flags["fill-map"] ?? `${report}.fill-map.json`
|
|
192
|
+
const fillEntries = projected ? edition.entries.filter((entry) => !projected.stale.includes(entry)) : existsSync(ownMap) ? readJsonFile(ownMap).entries : null
|
|
168
193
|
const result = checkFidelity(projected?.html ?? edition.text, {
|
|
169
194
|
ledger,
|
|
170
195
|
sourcesDir: resolve(flags.sources ?? join(sessionDir, "sources")),
|
|
171
196
|
claims: flags.claims !== undefined || existsSync(claimsPath) ? readJsonFile(claimsPath) : null,
|
|
172
197
|
fillMap: projected?.stale ?? edition.entries,
|
|
198
|
+
fillEntries,
|
|
173
199
|
brief: existsSync(briefPath) ? readText(briefPath) : "",
|
|
174
200
|
baseDir: dirname(resolve(report)),
|
|
175
201
|
recompute,
|
|
176
202
|
})
|
|
177
|
-
const
|
|
178
|
-
const
|
|
203
|
+
const checked = projected?.html ?? edition.text
|
|
204
|
+
const pointers = [...checked.matchAll(/\bdata-fact="([^"]+)"/gu)].map((match) => ({ token: match[0], start: match.index, parsed: { id: match[1] } }))
|
|
205
|
+
const mapPath = fillMapOf(report, edition.text, flags["fill-map"])
|
|
206
|
+
const bound = briefBindingErrors(mapPath === null ? null : readJsonFile(mapPath), mapPath ?? `${report}.fill-map.json`, parsed)
|
|
207
|
+
const defects = [...bound, ...policyErrors(checked, pointers, ledger, sessionDir, policy).errors, ...result.defects]
|
|
208
|
+
const counts = countDefects(defects)
|
|
209
|
+
const status = defects.some(blocksDelivery) ? "fail" : "pass"
|
|
179
210
|
const exitCode = status === "fail" ? 1 : 0
|
|
180
211
|
const out = resolve(flags.out ?? join(sessionDir, FIDELITY_RECORD))
|
|
181
|
-
const record = writeFidelityRecord(out, "fidelity", { command: "fact verify", status, exitCode, format: edition.format, report: resolve(report), artifact_sha256: sha256Of(edition.text), defects
|
|
212
|
+
const record = writeFidelityRecord(out, "fidelity", { command: "fact verify", status, exitCode, format: edition.format, report: resolve(report), artifact_sha256: sha256Of(edition.text), defects, counts, gatesRun: result.gatesRun })
|
|
182
213
|
return { json: { ...record, out }, summary: `fact verify: ${status.toUpperCase()} - ${counts.blocker} blocker, ${counts.major} major, ${counts.minor} minor`, exitCode }
|
|
183
214
|
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
// fact-commands.mjs - the `fact` subcommands of report-tools: add, quote, retract, export,
|
|
2
|
-
//
|
|
3
|
-
// polish-diff (fact-commands-polish.mjs). Every value reaches the ledger from a source
|
|
1
|
+
// fact-commands.mjs - the `fact` subcommands of report-tools: add, quote, retract, export, derive,
|
|
2
|
+
// fill (fact-commands-fill.mjs), verify (fact-commands-verify.mjs), pairs and meaning-check
|
|
3
|
+
// (fact-commands-meaning.mjs), polish-apply and polish-diff (fact-commands-polish.mjs). Every value reaches the ledger from a source
|
|
4
4
|
// snapshot through a deterministic locator or from a declared derivation; nothing here accepts a
|
|
5
5
|
// typed value. add and quote print the row with 60 chars of source context on each side (JSON
|
|
6
6
|
// with --json). Exit 0 ok, 1 semantic failure (fact_not_located, fill errors, a refused
|
|
7
7
|
// derivation), 2 usage. node: builtins and sibling imports only.
|
|
8
8
|
|
|
9
9
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs"
|
|
10
|
-
import {
|
|
10
|
+
import { join, resolve } from "node:path"
|
|
11
11
|
|
|
12
|
-
import { CliError, parseArgs, sha256Of
|
|
12
|
+
import { CliError, parseArgs, sha256Of } from "./cli-support.mjs"
|
|
13
13
|
import { DEFECT_CODES } from "./contracts.mjs"
|
|
14
|
+
import { alteredIn } from "./conversion-probe.mjs"
|
|
14
15
|
import { derive } from "./fact-derive.mjs"
|
|
15
|
-
import { fill } from "./fact-fill.mjs"
|
|
16
16
|
import { addRow, readLedger, retractRow, supersedeRow, writeLedger } from "./fact-ledger.mjs"
|
|
17
17
|
import { locateFind, locateMatch, locatePageLine, locateTable } from "./fact-locate.mjs"
|
|
18
18
|
import { QUALIFIER_FORMS } from "./fidelity-lexicon.mjs"
|
|
19
|
-
import { readState, writeState } from "./fidelity-state.mjs"
|
|
20
19
|
import { exportRows } from "./fidelity-values.mjs"
|
|
20
|
+
import { rawLocated } from "./raw-locator.mjs"
|
|
21
21
|
import { pointedFlag, sessionDirOf, snapshotOf } from "./source-commands.mjs"
|
|
22
22
|
|
|
23
23
|
const CONTEXT = 60
|
|
@@ -33,26 +33,30 @@ function readText(path) {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
/** A caller-supplied --now value as ISO; parsing only, never the clock. */
|
|
37
|
+
function isoOf(text) {
|
|
38
|
+
const date = new Date(text)
|
|
38
39
|
if (Number.isNaN(date.getTime())) throw new CliError("--now requires an ISO timestamp")
|
|
39
40
|
return date.toISOString()
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
const nowIso = (flags) => (flags.now === undefined ? new Date().toISOString() : isoOf(flags.now))
|
|
44
|
+
|
|
42
45
|
function failure(command, error, detail) {
|
|
43
46
|
const json = { command, status: "fail", exitCode: 1, error, ...detail }
|
|
44
47
|
return { json, summary: `${command}: ${error}${detail.message ? ` (${detail.message})` : ""}`, exitCode: 1 }
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
/** Every locator reads the view text (visible text nodes for a page), never raw markup. */
|
|
51
|
+
function locate(flags, view, id, quote) {
|
|
48
52
|
const sourceId = id
|
|
49
|
-
if (quote) return locateMatch(
|
|
50
|
-
if (flags.find !== undefined) return locateFind(
|
|
53
|
+
if (quote) return locateMatch(view.text, { match: flags.match, sourceId })
|
|
54
|
+
if (flags.find !== undefined) return locateFind(view.text, { find: flags.find, unitExpected: flags["unit-expected"], sourceId })
|
|
51
55
|
if (flags.table !== undefined) {
|
|
52
|
-
if (
|
|
53
|
-
return locateTable(
|
|
56
|
+
if (view.root === null) throw new CliError(`source ${id} is not an HTML page snapshot; --table needs one`)
|
|
57
|
+
return locateTable(view, { table: flags.table, row: flags.row, col: flags.col, sourceId })
|
|
54
58
|
}
|
|
55
|
-
if (flags.page !== undefined) return locatePageLine(
|
|
59
|
+
if (flags.page !== undefined) return locatePageLine(view.text, { page: Number(flags.page), line: Number(flags.line), sourceId })
|
|
56
60
|
throw new CliError("usage: fact add --source S<n> (--find TEXT | --table T --row R --col C | --page P --line L) --label LABEL")
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -79,11 +83,17 @@ function runAdd(args, quote) {
|
|
|
79
83
|
const id = args.required("source")
|
|
80
84
|
if (quote) args.required("match")
|
|
81
85
|
const sessionDir = sessionDirOf(flags)
|
|
82
|
-
const
|
|
83
|
-
const
|
|
86
|
+
const { meta, view, sha256, drift } = snapshotOf(sessionDir, id)
|
|
87
|
+
const converted = view.mode === "converted"
|
|
88
|
+
if (drift.length > 0) return failure(command, "snapshot_hash_mismatch", { message: `${id}: ${drift.join("; ")}` })
|
|
89
|
+
if (view.mode === "legacy") return failure(command, "snapshot_not_raw", { message: `${id} is a legacy text.txt snapshot without raw.bin; snapshot the source again under a new id` })
|
|
90
|
+
if (converted && !quote) return failure(command, "snapshot_not_raw", { message: `${id} is converted-only (no raw bytes); measured rows need source snapshot --raw <original> --text <extraction>` })
|
|
91
|
+
const located = locate(flags, view, id, quote)
|
|
92
|
+
const found = rawLocated(view, located)
|
|
84
93
|
if (found.error === "unit_expected_mismatch") return failure(command, "unit_mismatch", { message: `expected ${found.expected}, found ${found.found}`, candidates: found.candidates })
|
|
85
94
|
if (found.error) return failure(command, found.error, { message: `no single match in ${id}`, candidates: found.candidates })
|
|
86
|
-
const
|
|
95
|
+
const altered = alteredIn(join(sessionDir, "sources", id), [found.raw, found.quote])
|
|
96
|
+
if (altered.length > 0) return failure(command, "conversion_altered_number", { message: `${id}'s conversion altered ${[...new Set(altered)].join(", ")} (sources/${id}/conversion.json); the converted text cannot back this number, even where the source also shows it unaltered: write a verified text of the source and run \`source snapshot --id ${id} --text <verified.txt> --replace\`, then add the fact again`, tokens: altered, hint: DEFECT_CODES.conversion_altered_number.hint })
|
|
87
97
|
const host = URL.canParse(meta.url) ? new URL(meta.url).hostname : null
|
|
88
98
|
const labelSource = flags.find ?? flags.match ?? (flags.table !== undefined ? `${flags.row}_${flags.col}` : `p${flags.page}_l${flags.line}`)
|
|
89
99
|
const ledger = readLedger(sessionDir)
|
|
@@ -92,9 +102,10 @@ function runAdd(args, quote) {
|
|
|
92
102
|
...(quote ? {} : { value: found.value, unit: found.unit, value_span: found.value_span, qualifier: QUALIFIER_OF.get(found.qualifier) ?? null }),
|
|
93
103
|
raw: found.raw,
|
|
94
104
|
quote: found.quote,
|
|
105
|
+
context: found.context,
|
|
95
106
|
source_id: id,
|
|
96
107
|
locator: { ...found.locator, source_kind: meta.kind, url: meta.url, host, pointed: pointedFlag(sessionDir, meta.url) },
|
|
97
|
-
snapshot_sha256:
|
|
108
|
+
snapshot_sha256: sha256,
|
|
98
109
|
sentence_id: found.sentence_id ?? null,
|
|
99
110
|
extracted_by: meta.extractor,
|
|
100
111
|
observed_at: nowIso(flags),
|
|
@@ -107,11 +118,14 @@ function runAdd(args, quote) {
|
|
|
107
118
|
fuzzy: found.fuzzy === true,
|
|
108
119
|
})
|
|
109
120
|
writeLedger(sessionDir, ledger)
|
|
110
|
-
const context = contextOf(
|
|
111
|
-
const
|
|
121
|
+
const context = contextOf(view.text, located)
|
|
122
|
+
const { severity, integrity } = DEFECT_CODES.quote_converted_only
|
|
123
|
+
const defects = converted ? [{ code: "quote_converted_only", severity, integrity, message: `${id} is converted-only; the quote is not bound to the original fetched bytes` }] : []
|
|
124
|
+
const json = { command, status: "pass", exitCode: 0, defects, data: { row, context } }
|
|
112
125
|
if (flags.json) return { json, exitCode: 0 }
|
|
113
126
|
const shown = quote ? row.quote : `${row.raw} (value ${row.value}${row.unit ? `, unit ${row.unit}` : ""})`
|
|
114
|
-
|
|
127
|
+
const warnings = defects.map((defect) => `\n warning ${defect.code}: ${defect.message}`).join("")
|
|
128
|
+
return { text: `${row.fact_id} ${row.label}: ${shown} [${id} ${row.sentence_id ?? "-"}]\n ...${context.before}[${context.match}]${context.after}...${warnings}`, exitCode: 0 }
|
|
115
129
|
}
|
|
116
130
|
|
|
117
131
|
function runRetract(args) {
|
|
@@ -157,52 +171,16 @@ function runExport(args) {
|
|
|
157
171
|
return { json: { command: "fact export", status: "pass", exitCode: 0, data: { out: resolve(args.flags.out), format: args.flags.csv ? "csv" : "json", sha256: sha256Of(text), coverage } }, summary: coverage, exitCode: 0 }
|
|
158
172
|
}
|
|
159
173
|
|
|
160
|
-
/** The inline edition: local stylesheets and scripts inlined, relative image paths made absolute. */
|
|
161
|
-
function inlineAssets(html, baseDir) {
|
|
162
|
-
const local = (ref) => !/^[a-z][a-z0-9+.-]*:|^\/\//i.test(ref)
|
|
163
|
-
return html
|
|
164
|
-
.replace(/<link\b[^>]*\brel=["']stylesheet["'][^>]*>/gi, (tag) => {
|
|
165
|
-
const href = /\bhref=["']([^"']+)["']/i.exec(tag)?.[1]
|
|
166
|
-
return href && local(href) ? `<style>${readText(resolve(baseDir, href))}</style>` : tag
|
|
167
|
-
})
|
|
168
|
-
.replace(/<script\b([^>]*)\bsrc=["']([^"']+)["']([^>]*)><\/script>/gi, (tag, pre, src, post) => (local(src) ? `<script${pre}${post}>${readText(resolve(baseDir, src))}</script>` : tag))
|
|
169
|
-
.replace(/(<img\b[^>]*\bsrc=["'])([^"']+)(["'])/gi, (tag, pre, src, post) => (local(src) && !src.startsWith("/") ? `${pre}${resolve(baseDir, src)}${post}` : tag))
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function runFill(args) {
|
|
173
|
-
const [source] = args.positionals
|
|
174
|
-
const { flags } = args
|
|
175
|
-
if (!source || (flags.out === undefined && !flags.view)) throw new CliError("usage: fact fill <src> (--out <path> | --view) [--format html|md|tex] [--inline] [--replace-failed]")
|
|
176
|
-
const format = flags.format ?? ({ ".md": "md", ".tex": "tex" }[extname(source).toLowerCase()] ?? "html")
|
|
177
|
-
if (!["html", "md", "tex"].includes(format)) throw new CliError("--format must be html, md, or tex")
|
|
178
|
-
if (flags.inline && format !== "html") throw new CliError("--inline applies to the html edition only")
|
|
179
|
-
const sessionDir = sessionDirOf(flags)
|
|
180
|
-
const state = flags["replace-failed"] ? readState(sessionDir) : null
|
|
181
|
-
const result = fill(readText(source), readLedger(sessionDir), { format: format === "tex" ? "md" : format, view: flags.view === true, ...(state ? { replaceFailed: state } : {}) })
|
|
182
|
-
const warnings = result.warnings
|
|
183
|
-
if (result.out === null) {
|
|
184
|
-
const defects = result.errors.map((error) => ({ ...error, severity: DEFECT_CODES[error.code]?.severity ?? "blocker", hint: DEFECT_CODES[error.code]?.hint ?? null }))
|
|
185
|
-
return { json: { command: "fact fill", status: "fail", exitCode: 1, defects, warnings }, summary: `fact fill: FAIL - ${defects.length} error(s), nothing written`, exitCode: 1 }
|
|
186
|
-
}
|
|
187
|
-
const out = flags.inline ? inlineAssets(result.out, dirname(resolve(source))) : result.out
|
|
188
|
-
if (flags.view) return { text: out, summary: `fact fill --view: ${result.fillMap.length} pointer(s), ${warnings.length} warning(s)`, exitCode: 0 }
|
|
189
|
-
writeFileSync(flags.out, out)
|
|
190
|
-
if (state) writeState(sessionDir, state)
|
|
191
|
-
const artifact = sha256Of(out)
|
|
192
|
-
const map = `${resolve(flags.out)}.fill-map.json`
|
|
193
|
-
writeJsonAtomic(map, { schemaVersion: 1, format, artifact: resolve(flags.out), artifact_sha256: artifact, entries: result.fillMap })
|
|
194
|
-
const data = { out: resolve(flags.out), map, artifact_sha256: artifact, occurrences: result.fillMap.length, warnings }
|
|
195
|
-
return { json: { command: "fact fill", status: "pass", exitCode: 0, defects: [], data }, summary: `fact fill: wrote ${flags.out} (${result.fillMap.length} pointer(s))`, exitCode: 0 }
|
|
196
|
-
}
|
|
197
|
-
|
|
198
174
|
function runDerive(args) {
|
|
199
175
|
const { flags } = args
|
|
200
176
|
const op = args.required("op")
|
|
177
|
+
// Time is the caller's: without --now the CLI refuses with the library's missing_now code (exit 2) and never reads the clock.
|
|
178
|
+
if (flags.now === undefined) throw new CliError("missing_now: fact derive needs --now <ISO timestamp> (the row's observed_at); no row written")
|
|
201
179
|
const sessionDir = sessionDirOf(flags)
|
|
202
180
|
const ledger = readLedger(sessionDir)
|
|
203
181
|
// The registry refuses any field outside the operation's inputFields, so only the given flags go in; --unit null declares a dimensionless result.
|
|
204
182
|
const picked = ["to", "from", "num", "den", "part", "whole", "reference", "rationale", "label"].filter((key) => flags[key] !== undefined)
|
|
205
|
-
const spec = { op, now:
|
|
183
|
+
const spec = { op, now: isoOf(flags.now), ...Object.fromEntries(picked.map((key) => [key, flags[key]])) }
|
|
206
184
|
if (op === "expr") spec.formula = args.positionals[0]
|
|
207
185
|
else if (args.positionals.length > 0) spec.operands = args.positionals
|
|
208
186
|
if (flags.disjoint === true) spec.disjoint = true
|
|
@@ -230,7 +208,7 @@ export async function runFact(argv) {
|
|
|
230
208
|
case "export":
|
|
231
209
|
return runExport(args)
|
|
232
210
|
case "fill":
|
|
233
|
-
return
|
|
211
|
+
return (await import("./fact-commands-fill.mjs")).runFactFill(args)
|
|
234
212
|
case "derive":
|
|
235
213
|
return runDerive(args)
|
|
236
214
|
case "verify":
|
|
@@ -3,7 +3,7 @@ import { leaves, parseExpr } from "./fact-expr.mjs"
|
|
|
3
3
|
import { readRow } from "./fact-ledger-kinds.mjs"
|
|
4
4
|
import { addRow, nextId, validateLedger } from "./fact-ledger.mjs"
|
|
5
5
|
import { recompute, verifyGraph } from "./fact-recompute.mjs"
|
|
6
|
-
import { canonicalUnit, inputScale, refuse } from "./unit-algebra.mjs"
|
|
6
|
+
import { canonicalUnit, inputScale, refuse, RuleError } from "./unit-algebra.mjs"
|
|
7
7
|
import { refusal } from "./unit-errors.mjs"
|
|
8
8
|
import { object, sameDeclared } from "./unit-metadata.mjs"
|
|
9
9
|
import { display, renderValue, resultPrecision, toText } from "./unit-precision.mjs"
|
|
@@ -29,7 +29,11 @@ function declaredUnit(spec, rule) {
|
|
|
29
29
|
return canonicalUnit(declared)
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/** Refused before any work, under its own code: time is the caller's (spec.now), never the clock. */
|
|
33
|
+
const MISSING_NOW = Object.freeze({ error: "missing_now", shape: "missing_now", expected: "an ISO timestamp in spec.now", detail: "derive needs a caller-supplied now timestamp" })
|
|
34
|
+
|
|
32
35
|
export function derive(ledger, spec) {
|
|
36
|
+
if (object(spec) && typeof spec.now !== "string") return { ...MISSING_NOW }
|
|
33
37
|
try {
|
|
34
38
|
if (!object(spec)) refuse("spec must be an object")
|
|
35
39
|
const errors = validateLedger(ledger)
|
|
@@ -54,13 +58,14 @@ export function derive(ledger, spec) {
|
|
|
54
58
|
const result = compute(spec.op, rows, expected, ast, context, spec.formula)
|
|
55
59
|
const row = addRow(ledger, {
|
|
56
60
|
kind: rule.kind, unit: expected, quote: "", extracted_by: "fact-derive",
|
|
57
|
-
observed_at: spec.now
|
|
61
|
+
observed_at: spec.now,
|
|
58
62
|
label: spec.label ?? `${spec.op}-${nextId(ledger, rule.kind).toLowerCase()}`,
|
|
59
63
|
...result, operation: spec.op, operands: ids, derived_from: ids,
|
|
60
64
|
rationale: spec.rationale ?? null, context,
|
|
61
65
|
})
|
|
62
66
|
return { row, compatibility: rule.compatibility }
|
|
63
67
|
} catch (error) {
|
|
68
|
+
if (!(error instanceof RuleError)) throw error
|
|
64
69
|
return { error: "incompatible_operands", ...refusal(error) }
|
|
65
70
|
}
|
|
66
71
|
}
|