oh-my-opencode 5.1.48 → 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 -316
- package/dist/skills/ulw-research/references/deliverable-phase.md +23 -21
- 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 +12 -5
- 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 +13 -4
- package/dist/skills/ulw-research/scripts/contracts.test.ts +6 -110
- 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-polish.test.ts +4 -3
- 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 +11 -1
- package/dist/skills/ulw-research/scripts/fact-commands-meaning.mjs +13 -9
- package/dist/skills/ulw-research/scripts/fact-commands-polish.mjs +40 -18
- package/dist/skills/ulw-research/scripts/fact-commands-verify.mjs +25 -8
- package/dist/skills/ulw-research/scripts/fact-commands.mjs +35 -16
- 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 +6 -4
- 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 +4 -4
- 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 +5 -800
- package/dist/skills/ulw-research/scripts/snapshot-readability.test.ts +116 -0
- package/dist/skills/ulw-research/scripts/source-commands.mjs +79 -26
- 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 -316
- package/packages/omo-codex/plugin/skills/ulw-research/references/deliverable-phase.md +23 -21
- 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 +12 -5
- 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 +13 -4
- 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 +11 -1
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-meaning.mjs +13 -9
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-polish.mjs +40 -18
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands-verify.mjs +25 -8
- package/packages/omo-codex/plugin/skills/ulw-research/scripts/fact-commands.mjs +35 -16
- 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 +6 -4
- 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 +4 -4
- 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 +79 -26
- 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 -316
- package/packages/shared-skills/skills/ulw-research/references/deliverable-phase.md +23 -21
- 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 +12 -5
- 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 +13 -4
- package/packages/shared-skills/skills/ulw-research/scripts/contracts.test.ts +6 -110
- 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-polish.test.ts +4 -3
- 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 +11 -1
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-meaning.mjs +13 -9
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-polish.mjs +40 -18
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands-verify.mjs +25 -8
- package/packages/shared-skills/skills/ulw-research/scripts/fact-commands.mjs +35 -16
- 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 +6 -4
- 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 +4 -4
- 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 +5 -800
- 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 +79 -26
- 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
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
## Phase 3 — Verify contested claims by running code
|
|
2
|
+
|
|
3
|
+
Settle with executed code, not judgment, whenever sources disagree, a behavior is undocumented, a claim is performance- or compatibility-shaped, or the honest answer is "it should work". Spawn one verification worker per claim:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
task(category="deep-low", run_in_background=true, prompt="TASK: verify by execution: <claim>.
|
|
7
|
+
SOURCE: <where it came from>; CONTRADICTION: <opposing source, if any>.
|
|
8
|
+
Write a minimal self-contained script that tests the claim; run it (uv run --with <deps> python / bun / direct compile); capture full stdout+stderr; pin versions.
|
|
9
|
+
Reply with: the exact code, the full output, environment (OS, runtime, dependency versions), and a verdict — CONFIRMED / REFUTED / PARTIAL — grounded in the output.")
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Journal each verdict to `verify-<slug>.md`.
|
|
13
|
+
|
|
14
|
+
## Phase 3b — Lock non-code claims through the claim graph
|
|
15
|
+
|
|
16
|
+
Code settles code-shaped claims (Phase 3). Numeric, market-share, legal, dated, causal, and financial claims cannot be run — so they pass through a data-flow-lock instead (the verification idea adapted from fivetaku/insane-research): the synthesis may assert a high-risk non-code claim **only** if it cleared this gate, and the gate's output is the sole allowlist the synthesis draws from. Skip the gate and there is nothing to synthesize — the lock is self-enforcing.
|
|
17
|
+
|
|
18
|
+
The claim graph is orchestrator-owned. Workers only return verified-claim markers, observation candidates, and claim candidates as message text, the same channel as EXPAND markers — never a file (except a mass-research dag node's handoff file). As leads resolve, you record one node per asserted claim in `claim-graph.md` and compute its status; workers report claim candidates in their replies, and you decide. The graph is the single claim store: final synthesis may not draw from free-form claims that skipped it.
|
|
19
|
+
|
|
20
|
+
A high-risk claim clears the gate to `verified-claims` only when all hold:
|
|
21
|
+
|
|
22
|
+
- **>= 2 independent source domains** corroborate it (two pages on the same domain count once).
|
|
23
|
+
- **>= 2 independent observation groups** converge on it, unless the graph records why a primary-only source is the correct single-source exception.
|
|
24
|
+
- **One counter-search** actively looked for a refutation and did not find a stronger one.
|
|
25
|
+
- **A primary source** (the standard, filing, dataset, or first-party doc) backs it, not only secondary commentary.
|
|
26
|
+
- **Temporal evidence is explicit**: each supporting observation records `observed_at` and either `valid_at` or `claim_valid_at`, so branch-only, historical, release, and current-runtime claims cannot be conflated.
|
|
27
|
+
|
|
28
|
+
Anything that fails goes to an `Unresolved` (insufficient evidence) or `Refuted` (counter-search won) annex — abstention is a correct outcome, not a gap to paper over. Record each gate outcome on the claim node itself — risk tier, independent source domains, counter-search result, primary source backing, and status — and mirror the cleared nodes into the `verified-claims` digest section at the top of `claim-graph.md`. Worker reply marker (message text, same channel as EXPAND):
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
## CLAIMS
|
|
32
|
+
- CLAIM: <non-code assertion> — RISK: high|normal — SOURCES: <domain1, domain2> — COUNTER: <refutation search result> — PRIMARY: <primary source or none>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**The claim table is machine-read.** Keep the nodes of `claim-graph.md` in one Markdown table whose header names `claim_id | statement | risk tier | status` (plus `fact_ids`, the ledger rows the node rests on, and any other node fields as further columns), one row per node: ids `C<n>`, risk `high` or `normal`, status `supported`, `partial`, `refuted`, or `unresolved`. List the nodes that clear the Phase 3b gate under a `## verified-claims` heading as `- C<n>: <statement>`. `node "$SKILL_DIR/scripts/report-tools.mjs" claims index "$SESSION_DIR/claim-graph.md" --out "$SESSION_DIR/claims.json"` indexes it, and the fidelity gate reads `claims.json` to check every `data-claim` binding in the report.
|
|
36
|
+
|
|
37
|
+
## Phase 4 — Synthesize
|
|
38
|
+
|
|
39
|
+
After convergence and all verifications, re-read the whole journal, start from `intent-diff.md`, `claim-graph.md`, and `observation-manifest.md`, then write `SYNTHESIS.md`:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
# ULW-Research Synthesis: <query>
|
|
43
|
+
Workers: <total> · Waves: <count> · Excursions: <count> · Sources: <count> (<unique domains> domains) · Verifications: <count> · Elapsed: <minutes> min
|
|
44
|
+
|
|
45
|
+
## Executive summary — 2-3 paragraphs answering the core question
|
|
46
|
+
## Findings by theme — per theme: consensus, evidence links, key quote (<20 words, attributed), verified yes/no
|
|
47
|
+
## Codebase findings — absolute paths with line references
|
|
48
|
+
## Sources (ranked) — URL, what it contains, reliability, access date
|
|
49
|
+
## Verified claims — code: claim | verdict | verify-<slug>.md · non-code: only rows cleared into verified-claims
|
|
50
|
+
## Epistemic instrumentation — intent-vs-reality diff closure, claim graph coverage, observation manifest coverage, independent-observation convergence, verification economics summary, cause-disappearance records
|
|
51
|
+
## Contradictions — source A vs source B, resolution with evidence
|
|
52
|
+
## Gaps — what saturation could not answer · unresolved/refuted claim-graph nodes
|
|
53
|
+
## Expansion trace — per wave: workers → markers; convergence reason
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`SYNTHESIS.md` is the citation source of truth for final materials: every claim carries inline `[Source N]` citations, and every high-risk non-code claim you assert must be a verified-claims row from Phase 3b. Assert nothing the gate left in the unresolved/refuted annex.
|
|
57
|
+
|
|
58
|
+
**Write numbers and quotes by reference.** `SYNTHESIS.md` and every report source carry placeholders, never typed values: `{{F12:span_len}}` renders the row's value and unit, `{{F12:span_len:value}}` or `:unit` one part, `:q` the value with its source qualifier (up to, at least, about); `{{Q7:completion}}` renders the whole quotation, `{{Q7:completion:lead=8}}` its first words, `{{Q7:completion:from="no earlier":to="2027"}}` one span of it. A derived number is computed by the script, never by hand: `fact derive --op sum|diff|growth|ratio|share|convert|expr ...` checks the operands' units, periods, and populations, refuses an incompatible operation, and prints the new row id the placeholder uses. A value nobody measured is registered with `fact add --assumed <value> --unit <unit> --rationale <why> --label <label>` and renders as ASSUMED. Every findings sentence binds to a fact, a quote, a `[S<n>]` citation, or a claim node (`data-claim="C3"`). Reviewers and the refinement team read the rendered text through `node "$SKILL_DIR/scripts/report-tools.mjs" fact fill "$SESSION_DIR/SYNTHESIS.md" --view --session-dir "$SESSION_DIR"`, never the raw placeholders.
|
|
59
|
+
|
|
60
|
+
**Write the skeleton early and fill it as claims lock.** The moment the brief records the deliverable, create the deliverable file with its section headings and a `STATUS: draft — <n> sections open` line as line 2 (an HTML comment in HTML); that line is the partial-state marker `outcome state` reads, removed only when the deliverable is complete. An interrupted run must leave a partial report on disk, never an empty directory and a lost conversation.
|
|
61
|
+
|
|
62
|
+
**Keep sourced numbers, assumptions, and derived results visibly apart.** Every quantitative claim carries its lineage: `MEASURED` (a number a source states, cited), `ASSUMED` (a coefficient, distribution, or scope you chose — say why), `DERIVED` (computed from those, showing the formula), plus a sensitivity line whenever the assumption moves the answer. Presenting a derived estimate with the confidence of a measured one is the most damaging thing this mode can ship.
|
|
63
|
+
|
|
64
|
+
**Search in English, deliver in the user's language.** Retrieval stays English-first (Search craft), but the synthesis and every final material are written in the language the user wrote to you in unless they ask otherwise — and a translated report still quotes its original-language sources verbatim.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
## Search craft
|
|
68
|
+
|
|
69
|
+
English first: run every search in English by default — it is the largest, most authoritative corpus on every engine, GitHub, and documentation site. Add a secondary local-language sweep (1-2 librarians) only after the English sweep, when the topic is inherently local, or when the user asks for sources in a specific language.
|
|
70
|
+
|
|
71
|
+
Vary operators on every query — same query twice wastes a worker:
|
|
72
|
+
|
|
73
|
+
| Operator | Example | Use |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `site:` | `site:github.com <topic>` | Restrict to a domain |
|
|
76
|
+
| `filetype:` | `filetype:pdf <topic> survey` | Papers, specs |
|
|
77
|
+
| `intitle:` / `inurl:` | `intitle:benchmark <topic>` | Targeted pages |
|
|
78
|
+
| `"exact"` / `-term` | `"<exact phrase>" -tutorial` | Precision, exclusion |
|
|
79
|
+
| `OR` | `<a> OR <b> <topic>` | Coverage |
|
|
80
|
+
| `before:` / `after:` | `<topic> after:2025-06-01` | Recency control |
|
|
81
|
+
|
|
82
|
+
High-yield combinations: official docs (`site:<docs domain>`), GitHub implementations (`site:github.com`), recent discussion (`site:reddit.com OR site:news.ycombinator.com after:<date>`), academic (`site:arxiv.org OR filetype:pdf survey`), changelog hunting (`changelog OR "release notes" <version>`), alternatives (`vs OR alternative OR comparison`).
|
|
83
|
+
|
|
84
|
+
## Failure modes
|
|
85
|
+
|
|
86
|
+
| Failure | Correction |
|
|
87
|
+
|---|---|
|
|
88
|
+
| Sequential spawning, or trimming the first wave | All first-wave workers in one turn, background, scaling floor respected |
|
|
89
|
+
| A team member hoards leads for one final dump | Raise law — every lead, finding, and dead end broadcast the moment it surfaces |
|
|
90
|
+
| Worker reply without the EXPAND tail | One follow-up demanding it; the lane stays open until it lands |
|
|
91
|
+
| Stopping after wave 1 because "enough was found" | Convergence rules only: 2+ expansion waves, leads run dry |
|
|
92
|
+
| Obeying a surrounding "stop exploring" rule mid-research | Authority section — those rules do not bind this mode |
|
|
93
|
+
| Asking a worker to write journal or session files | Workers are read-only (except a mass-research dag node's handoff file); you journal every return |
|
|
94
|
+
| Two workers given the same angle | One unique angle per worker, always |
|
|
95
|
+
| A web worker that returned only fetched text, or a `Collection: browser` run whose workers never opened a tab | Sources are read in the user's browser through the `browser` skill; `webfetch` is for raw files; every web worker carries the skill from the first wave |
|
|
96
|
+
| Contested claim settled by judgment | Phase 3 — run code, capture output, verdict |
|
|
97
|
+
| Deliverable claims without citations | Every claim cites a source or a verification artifact |
|
|
98
|
+
| Guessing the deliverable format | Derive it from the request and destination; ask the empty-info interview only for what is still missing, and record `answered_by` for every field |
|
|
99
|
+
| Blocking the collection wave on the format question | Ask non-blocking and start collecting; unanswered fields run on the shown defaults |
|
|
100
|
+
| A roster smaller than the harness ceiling | Fill every member slot; split the broadest axis until the team is full |
|
|
101
|
+
| One tier across the whole roster | Mixed tiers by design — cheap breadth, premium attack |
|
|
102
|
+
| Silently re-routing a "quick"/"fast" instruction | Routing words are literal; journal requested -> spawned -> fallback per slot |
|
|
103
|
+
| A worker or member that starts its own research swarm | Members research one axis and report; orchestration is yours alone |
|
|
104
|
+
| Expanding on an entity the first wave never disambiguated | Settle canonical identity and first-party source before any later spawn asserts it |
|
|
105
|
+
| Batching findings into an end-of-run journal dump | Journal each return as it lands; the journal is what survives a compaction |
|
|
106
|
+
| Ending the run because every worker finished | Reserve the final fifth of the run for synthesis and materials |
|
|
107
|
+
| A derived estimate presented as a measured number | MEASURED / ASSUMED / DERIVED lineage on every quantitative claim, plus a sensitivity line |
|
|
108
|
+
| A number typed into the report or `SYNTHESIS.md` | Register it (`fact add`) and write `{{F<n>:label}}`; `fact verify` reports a typed number as `untraceable_number`, and `outcome verify` refuses delivery until it is a ledger row, an `assumed` row with its rationale, or gone |
|
|
109
|
+
| A filled value edited by hand | Never edit a filled value: fix the ledger row or the placeholder and re-run `fact fill`, then `fact verify` (`value_mismatch`, `unit_mismatch`) |
|
|
110
|
+
| A findings sentence bound to nothing | Bind it to a fact, a quote, a `[S<n>]` citation, or a claim node with `data-claim`; an `unbound_sentence` blocks delivery like an untraceable number |
|
|
111
|
+
| Delivering before the delivery gates pass | Static and layout gates, visual QA on rendered pages, plus the harness's proofread gate — a typo the user finds means a gate did not run |
|
|
112
|
+
| Skipping the static gates | `report-tools check` runs before any pixel review; its defects are cheaper than a visual pass |
|
|
113
|
+
| Delivering with a pending manifest row | `outcome verify` must pass; every promised format ends `delivered`, `blocked_capability`, `skipped`, or `failed` with a reason |
|
|
114
|
+
| Repairing past the tracker's stop decision | `repair decide` owns the budget; `deliver` ships with the residual list, `block` stops delivery |
|
|
115
|
+
| Guessing a design-spec value the extractor marked `TODO: ask` | Fill it from the interview answers or the reference's defaults, never by guessing |
|
|
116
|
+
| Referencing an asset that is not on disk | Verify the asset manifest before rendering; re-render whatever is missing |
|
|
117
|
+
| A figure stretched, cropped, or styled off the report's design language | `design-spec.md` binds every asset: fixed containers, contain-fit with aspect preserved, spec fonts and palette in charts and Mermaid |
|
|
118
|
+
| Chasing an interesting find with no ENTER trigger | Excursions need a named trigger; everything else stays a queued lead |
|
|
119
|
+
| An excursion that never came back, or drifted into a new mission | EXIT rules are unconditional; depth 3 means promote it to an axis or record it as a gap |
|
|
120
|
+
| An excursion whose result was never folded back | Every EXIT writes what it changed in the top-level answer, `none` included, and mirrors into the loop ledger |
|
|
121
|
+
| Ending with file paths while an inline HTML page tool is available | Show the report inline first (the gated `report.html` or its inline edition), then the paths and the summary |
|
|
122
|
+
| A visual reproduction checked only against itself | Reference compare: real source frames next to renders at the same moments, a critique per pair, fixes, and the pairs in the report |
|
|
123
|
+
| Delivering without the closing briefing | Paste the block `outcome briefing` prints; never compute or recall its numbers by hand |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// emits it as the data-claim-kind attribute on the element it renders, and the fidelity gate
|
|
5
5
|
// (fidelity-claims.mjs) checks that every marked element cites a row the kind accepts. An
|
|
6
6
|
// unmarked element is a plain fact or quote and is checked only by the value and quote checks.
|
|
7
|
-
// The one lexical piece is `unmarked`:
|
|
7
|
+
// The one lexical piece is `unmarked`: first-person run and check patterns that raise a minor warning
|
|
8
8
|
// when a sentence reads like the kind but carries no mark; they never raise a major. The table in
|
|
9
9
|
// references/fidelity-claim-kinds.md is rendered from CLAIM_KINDS (`node claim-kinds.mjs --render-doc`).
|
|
10
10
|
// Pure; node: builtins only. Korean phrases are \u escapes.
|
|
@@ -23,6 +23,32 @@ const KO_WE_RUN = "(?:\uC2E4\uD589(?:\uD588|\uD558\uC5EC|\uD574)|\uB3CC[\uB838\u
|
|
|
23
23
|
const KO_RUN = "(?:\uC2E4\uD589|\uB3CC[\uB9AC\uB824\uB838\uB9B0\uB9B4])"
|
|
24
24
|
const KO_SUBJECT = "[^\\s,.;!?]*(?:[\uAC00\uC774\uC740\uB294]|\uAED8\uC11C)(?=\\s)"
|
|
25
25
|
|
|
26
|
+
// One cue list; the rule text below is built from it. A check verb fires only in first person with
|
|
27
|
+
// a result object (a result noun or a digit) in its clause, and never when that clause names a document.
|
|
28
|
+
// The document guard ends where the clause ends (a comma, a semicolon, "as", a relative pronoun; in Korean a
|
|
29
|
+
// comma, a semicolon, cheoreom, deusi, gati), and a document word followed by a number is a locator ("page 3").
|
|
30
|
+
const EN_RUN = ["ran", "run", "re-ran", "re-run", "executed", "verified by"]
|
|
31
|
+
const EN_CHECK = ["verified", "checked", "confirmed", "measured", "tested", "double-checked", "cross-checked"]
|
|
32
|
+
const EN_RESULT = ["value", "values", "result", "results", "figure", "figures", "number", "numbers", "total", "totals", "count", "counts", "measurement", "measurements", "reading", "readings", "output", "outputs", "span", "length", "rate", "rates", "latency", "throughput", "score", "scores", "benchmark", "benchmarks", "metric", "metrics", "data", "estimate", "estimates", "speed", "duration", "size", "ratio", "growth"]
|
|
33
|
+
const EN_DOCUMENT = ["report", "reports", "filing", "filings", "document", "documents", "paper", "papers", "article", "articles", "publication", "statement", "disclosure", "website", "page", "docs", "documentation"]
|
|
34
|
+
// KO_CHECK = hwagin, geomjeung, cheukjeong, jeomgeom (+ haet/hayeot/hayeo/hae/han); KO_RESULT = gyeolgwa, gap, suchi, gil-i, hapgye,
|
|
35
|
+
// biyul, sokdo, jipyo, deiteo; KO_DOCUMENT = bogoseo, munseo, gongsi, nonmun, gisa, jaryo.
|
|
36
|
+
const KO_CHECK = ["\uD655\uC778", "\uAC80\uC99D", "\uCE21\uC815", "\uC810\uAC80"]
|
|
37
|
+
const KO_DONE = ["\uD588", "\uD558\uC600", "\uD558\uC5EC", "\uD574", "\uD55C"]
|
|
38
|
+
const KO_RESULT = ["\uACB0\uACFC", "\uAC12", "\uC218\uCE58", "\uAE38\uC774", "\uD569\uACC4", "\uBE44\uC728", "\uC18D\uB3C4", "\uC9C0\uD45C", "\uB370\uC774\uD130"]
|
|
39
|
+
const KO_DOCUMENT = ["\uBCF4\uACE0\uC11C", "\uBB38\uC11C", "\uACF5\uC2DC", "\uB17C\uBB38", "\uAE30\uC0AC", "\uC790\uB8CC"]
|
|
40
|
+
const any = (words) => words.map((word) => word.replace(/-/g, "-?").replace(/ /g, "\\s+")).join("|")
|
|
41
|
+
const EN_WE = "(?:\\b[Ww]e|\\bI)(?:'ve|'d)?\\s+(?:(?:have|had|also|then|first|just|again|independently|manually|directly)\\s+)*"
|
|
42
|
+
const CLAUSE = "(?:[^.;!?]|\\.\\d)*?"
|
|
43
|
+
const EN_BOUNDARY = ["as", "which", "who", "whom", "whose", "where"]
|
|
44
|
+
const KO_BOUNDARY = ["\uCC98\uB7FC", "\uB4EF\uC774", "\uAC19\uC774"]
|
|
45
|
+
const EN_GUARD = `(?:(?!,|\\b(?:${any(EN_BOUNDARY)})\\b)[^.;!?]|\\.\\d)*?`
|
|
46
|
+
const KO_GUARD = `(?:(?!,|${any(KO_BOUNDARY)})[^.;!?]|\\.\\d)*?`
|
|
47
|
+
const EN_OBJECT = `(?=${CLAUSE}(?:\\b(?:${any(EN_RESULT)})\\b|\\d))(?!${EN_GUARD}\\b(?:${any(EN_DOCUMENT)})\\b(?!\\s*\\d))`
|
|
48
|
+
const KO_OBJECT = `(?=${CLAUSE}(?:${any(KO_RESULT)}|\\d))(?!${KO_GUARD}(?:${any(KO_DOCUMENT)})(?!\\s*\\d))`
|
|
49
|
+
const escapes = (text) => text.replace(/[^\x00-\x7f]/g, (c) => `\\u${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`)
|
|
50
|
+
const list = (words) => escapes(words.join(", "))
|
|
51
|
+
|
|
26
52
|
/**
|
|
27
53
|
* kind -> { prefix: placeholder prefix (null = the default form), placeholder: an example,
|
|
28
54
|
* rowKinds: ledger row kinds it accepts, sourceKinds: meta.json kinds the snapshot holding the
|
|
@@ -50,11 +76,13 @@ export const CLAIM_KINDS = Object.freeze({
|
|
|
50
76
|
note: "The cited row itself must have a locator artifact inside `sources/<source_id>/` whose `meta.json` kind is `command`; another command row in the sentence never counts. Whether it is the right command for the claim is the meaning verifier's call (minor), not this gate's.",
|
|
51
77
|
unmarked: {
|
|
52
78
|
code: "verification_claim_unmarked",
|
|
53
|
-
rule:
|
|
79
|
+
rule: `a first-person run: we/I (have) ${list(EN_RUN)} (not ran out of), or by running after we/our in the sentence; a first-person check: we/I (have) ${list(EN_CHECK)} (not checked in/into/out) with a result object in the clause (${list(EN_RESULT)}, or a digit) and no document named before the clause ends (${list(EN_DOCUMENT)}; a comma, a semicolon, or ${list(EN_BOUNDARY)} ends it, and a document word followed by a number is a locator); \\uC6B0\\uB9AC or \\uC800\\uD76C as the subject word (+ \\uAC00, \\uB294, or \\uD300\\uC774), then \\uC2E4\\uD589\\uD588, \\uC2E4\\uD589\\uD558\\uC5EC, \\uC2E4\\uD589\\uD574, \\uB3CC\\uB838, or \\uB3CC\\uB824 in the clause with no third-party subject between, or then ${list(KO_CHECK)} + ${list(KO_DONE)} with a result object in the clause (${list(KO_RESULT)}, or a digit) and no document before the clause ends (${list(KO_DOCUMENT)}; a comma, a semicolon, or ${list(KO_BOUNDARY)} ends it, and a document word followed by a number is a locator); \\uC9C1\\uC811 with no third-party subject, then \\uC2E4\\uD589 or \\uB3CC\\uB9AC in the clause; a curly apostrophe reads as a straight one`,
|
|
54
80
|
patterns: [
|
|
55
|
-
|
|
56
|
-
|
|
81
|
+
new RegExp(`${EN_WE}(?:${any(EN_RUN)})\\b(?!\\s+out\\s+of\\b)`),
|
|
82
|
+
new RegExp(`${EN_WE}(?:${any(EN_CHECK)})\\b(?!\\s+(?:in|into|out)\\b)${EN_OBJECT}`),
|
|
83
|
+
/\b(?:[Ww]e|[Oo]ur)\b.*?\bby\s+running\b/,
|
|
57
84
|
new RegExp(`${KO_WE_SUBJECT}(?:(?!${KO_SUBJECT})[^\\s,.;!?]+\\s+)*?${KO_WE_RUN}`),
|
|
85
|
+
new RegExp(`${KO_WE_SUBJECT}${KO_OBJECT}(?:(?!${KO_SUBJECT})[^\\s,.;!?]+\\s+)*?(?:${any(KO_CHECK)})(?:${any(KO_DONE)})`),
|
|
58
86
|
new RegExp(`(?:^|[,.;!?])\\s*(?:(?!${KO_SUBJECT})[^\\s,.;!?]+\\s+)*\uC9C1\uC811\\s*(?:[^\\s,.;!?]+\\s*)??${KO_RUN}`),
|
|
59
87
|
],
|
|
60
88
|
},
|
|
@@ -86,7 +114,7 @@ export function unmarkedRequires(row) {
|
|
|
86
114
|
/** The kinds whose unmarked patterns match the sentence. */
|
|
87
115
|
export function unmarkedKinds(text) {
|
|
88
116
|
return Object.entries(CLAIM_KINDS)
|
|
89
|
-
.filter(([, entry]) => entry.unmarked?.patterns.some((re) => re.test(text)))
|
|
117
|
+
.filter(([, entry]) => entry.unmarked?.patterns.some((re) => re.test(String(text).replace(/\u2019/g, "'"))))
|
|
90
118
|
.map(([name]) => name)
|
|
91
119
|
}
|
|
92
120
|
|
|
@@ -127,7 +127,7 @@ describe("design-check regressions", () => {
|
|
|
127
127
|
test("#given the assumed row F9 unmarked or marked fact #then both refuse it, and the unmarked message names the A mark", () => {
|
|
128
128
|
expect(codes(prose(value(F9)))).toEqual(["claim_kind_mismatch"])
|
|
129
129
|
expect(codes(prose(value(F9, "fact")))).toEqual(["claim_kind_mismatch"])
|
|
130
|
-
expect(JSON.stringify(claims(prose(value(F9))))).toContain("{{A:F9}}")
|
|
130
|
+
expect(JSON.stringify(claims(prose(value(F9))))).toContain("{{A:F9:growth_rate}}")
|
|
131
131
|
})
|
|
132
132
|
|
|
133
133
|
test("#given the assumed row F9 marked {{A:F9}} (data-claim-kind=assumed) #then no claim defect", () => {
|
|
@@ -155,6 +155,21 @@ describe("unmarked phrases", () => {
|
|
|
155
155
|
"우리 팀이 벤치마크를 돌려 얻은 값",
|
|
156
156
|
"그래서 우리는 스크립트를 실행했다",
|
|
157
157
|
"직접 실행한 결과",
|
|
158
|
+
"우리는 결과를 확인했다",
|
|
159
|
+
"We confirmed the result.",
|
|
160
|
+
"We verified the span against the field log.",
|
|
161
|
+
"We double-checked the totals.",
|
|
162
|
+
"We cross-checked the values.",
|
|
163
|
+
"We\u2019ve confirmed the result.",
|
|
164
|
+
"We confirmed that the recorded span is up to 320 m.",
|
|
165
|
+
"We measured 42 ms.",
|
|
166
|
+
"저희는 측정값 320 m를 검증했다",
|
|
167
|
+
"We measured a latency of 40 ms, as this report shows.",
|
|
168
|
+
"We verified the value on page 3.",
|
|
169
|
+
"We checked the totals, which the filing also lists.",
|
|
170
|
+
"우리는 결과를 확인하였다",
|
|
171
|
+
"우리는 실행 결과를 검증하였다",
|
|
172
|
+
"우리는 지연 시간 40 ms를 측정했고, 보고서도 같은 값을 적었다",
|
|
158
173
|
]
|
|
159
174
|
const quiet = [
|
|
160
175
|
"The tests showed a 12 % drop.",
|
|
@@ -169,12 +184,32 @@ describe("unmarked phrases", () => {
|
|
|
169
184
|
"우리나라에서 실행된 정책은 320개다",
|
|
170
185
|
"우리 정부가 실행한 예산",
|
|
171
186
|
"우리가 의뢰한 업체가 테스트를 돌렸다",
|
|
172
|
-
"
|
|
187
|
+
"We checked the box to opt in.",
|
|
188
|
+
"As we observed in Section 2, demand is seasonal.",
|
|
189
|
+
"The values we observed were higher than the 2023 baseline.",
|
|
190
|
+
"We checked into the hotel.",
|
|
191
|
+
"We checked in at the hotel.",
|
|
192
|
+
"In Phase I observed values rose.",
|
|
193
|
+
"We confirmed the figure against the 2024 annual report.",
|
|
194
|
+
"We use confirmed values, validated inputs, checked references, observed events, and measured responses.",
|
|
195
|
+
"The authors confirmed that the value was measured.",
|
|
196
|
+
"우리는 보고서의 수치를 확인했다",
|
|
197
|
+
"우리는 일정을 확인했다",
|
|
198
|
+
"우리는 공시 자료의 수치를 확인하였다",
|
|
199
|
+
"We measured the latency in the published report.",
|
|
173
200
|
]
|
|
174
201
|
for (const text of fires) test(`#given "${text}" #then verified`, () => expect(unmarkedKinds(text)).toEqual(["verified"]))
|
|
175
202
|
for (const text of quiet) test(`#given "${text}" #then nothing`, () => expect(unmarkedKinds(text)).toEqual([]))
|
|
176
203
|
})
|
|
177
204
|
|
|
205
|
+
describe("references/report-gates.md lists the shipped cue rule", () => {
|
|
206
|
+
test("the verification_claim_unmarked glossary row carries CLAIM_KINDS.verified.unmarked.rule verbatim", () => {
|
|
207
|
+
const glossary = readFileSync(join(import.meta.dir, "..", "references", "report-gates.md"), "utf8")
|
|
208
|
+
const row = glossary.split("\n").find((line) => line.startsWith("| `verification_claim_unmarked` |")) ?? ""
|
|
209
|
+
expect(row).toContain(CLAIM_KINDS.verified.unmarked?.rule ?? "missing rule")
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
|
|
178
213
|
describe("references/fidelity-claim-kinds.md is rendered from CLAIM_KINDS", () => {
|
|
179
214
|
const doc = readFileSync(join(import.meta.dir, "..", "references", "fidelity-claim-kinds.md"), "utf8")
|
|
180
215
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import { readFileSync } from "node:fs"
|
|
3
|
+
import { join } from "node:path"
|
|
4
|
+
|
|
5
|
+
import { markdownAsHtml } from "./fact-commands-verify.mjs"
|
|
6
|
+
import { fill } from "./fact-fill.mjs"
|
|
7
|
+
import { valueChecks } from "./fidelity-values.mjs"
|
|
8
|
+
import { buildContext } from "./gates-static.mjs"
|
|
9
|
+
import { parseHtml } from "./html-lite.mjs"
|
|
10
|
+
import { parsePlaceholder, renderValueHtml } from "./placeholder.mjs"
|
|
11
|
+
|
|
12
|
+
type Row = Record<string, unknown> & { fact_id: string }
|
|
13
|
+
const FIX = join(import.meta.dir, "tests", "fixtures", "fidelity")
|
|
14
|
+
const BASE: { rows: Row[] } = JSON.parse(readFileSync(join(FIX, "ledger-verify.json"), "utf8"))
|
|
15
|
+
const row = (id: string) => BASE.rows.find((r) => r.fact_id === id) as Row
|
|
16
|
+
const converted = { ...row("F8"), raw: "320,000 mm (320 m)", render: "320,000 mm (320 m)", derived_from: ["F1"] }
|
|
17
|
+
const assumed = { ...row("F8"), fact_id: "F9", kind: "assumed", label: "plan", raw: "15%", render: null, value: "15", unit: "%", derived_from: [], operands: [], operation: null }
|
|
18
|
+
const ledger = { ...BASE, rows: [...BASE.rows.filter((r) => r.fact_id !== "F8"), converted, assumed] }
|
|
19
|
+
const check = (html: string) => valueChecks(buildContext(parseHtml(`<h2>Findings</h2>${html}`), { baseDir: FIX }), ledger, null, join(FIX, "sources"))
|
|
20
|
+
|
|
21
|
+
describe("claim prefixes come from the CLAIM_KINDS registry and combine with the pointer grammar", () => {
|
|
22
|
+
test("#given a prefix before a value mode or a quote selector #when parsed #then the pointer keeps its mode and gains the claim kind", () => {
|
|
23
|
+
expect(parsePlaceholder("{{D:F12:label}}")).toEqual({ id: "F12", kind: "F", label: "label", mode: "full", claimKind: "derived" })
|
|
24
|
+
expect(parsePlaceholder("{{D:F12:label:value}}")).toEqual({ id: "F12", kind: "F", label: "label", mode: "value", claimKind: "derived" })
|
|
25
|
+
expect(parsePlaceholder("{{V:Q7:label:lead=3}}")).toMatchObject({ id: "Q7", mode: "lead", lead: 3, claimKind: "verified" })
|
|
26
|
+
expect(parsePlaceholder("{{A:F9:plan}}")).toMatchObject({ id: "F9", claimKind: "assumed" })
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
for (const token of ["{{D:F12}}", "{{D:F12:}}", "{{D:F12:a:b}}", "{{V:F7}}", "{{A:}}", "{{X:F8:span_mm}}", "{{V:V:F7:test_pass}}", "{{D:F0:label}}"]) {
|
|
30
|
+
test(`#given the malformed ${token} #when filled #then unresolved_placeholder`, () => {
|
|
31
|
+
const result = fill(token, ledger)
|
|
32
|
+
expect(result.out).toBeNull()
|
|
33
|
+
expect((result.errors as { code: string }[]).map((e) => e.code)).toEqual(["unresolved_placeholder"])
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const [token, code] of [["{{A:F8:span_mm}}", "claim_kind_mismatch"], ["{{V:F8:span_mm}}", "unsupported_verification"]]) {
|
|
38
|
+
test(`#given ${token} on a row its kind refuses #when filled #then the kind's documented defect ${code}`, () => {
|
|
39
|
+
const result = fill(token, ledger)
|
|
40
|
+
expect(result.out).toBeNull()
|
|
41
|
+
expect((result.errors as { code: string }[]).map((e) => e.code)).toEqual([code])
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
describe("renderValueHtml takes { mode, claimKind }", () => {
|
|
47
|
+
test("#given a value-mode fact with a D claim #when rendered #then both the mode marker and the claim attribute are emitted", () => {
|
|
48
|
+
const html = renderValueHtml(converted, "320,000", { mode: "value", claimKind: "derived" })
|
|
49
|
+
expect(html).toContain('data-fact-mode="value"')
|
|
50
|
+
expect(html).toContain('data-claim-kind="derived"')
|
|
51
|
+
expect(renderValueHtml(converted, "320,000 mm")).not.toMatch(/data-fact-mode|data-claim-kind/)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test("#given {{D:F8:span_mm:value}} #when filled to HTML #then the element carries both attributes and the fill map records the mode", () => {
|
|
55
|
+
const result = fill("<p>{{D:F8:span_mm:value}} mm</p>", ledger)
|
|
56
|
+
expect(result.errors).toEqual([])
|
|
57
|
+
expect(result.out).toContain('data-fact-mode="value"')
|
|
58
|
+
expect(result.out).toContain('data-claim-kind="derived"')
|
|
59
|
+
expect(result.fillMap[0]).toMatchObject({ mode: "value", claimKind: "derived" })
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
describe("prefixed fills verify clean in HTML and Markdown", () => {
|
|
64
|
+
for (const [token, kind] of [["{{V:F7:test_pass}}", "verified"], ["{{A:F9:plan}}", "assumed"], ["{{D:F8:span_mm}}", "derived"]]) {
|
|
65
|
+
for (const format of ["html", "md"] as const) {
|
|
66
|
+
test(`#given ${token} filled as ${format} #when verified #then it carries ${kind} and raises nothing`, () => {
|
|
67
|
+
const result = fill(format === "html" ? `<p>${token} [S4].</p>` : `${token} [S4].`, ledger, { format })
|
|
68
|
+
expect(result.errors).toEqual([])
|
|
69
|
+
if (result.out === null) throw new Error("fill failed")
|
|
70
|
+
const html = format === "html" ? result.out : markdownAsHtml(result.out, result.fillMap as Parameters<typeof markdownAsHtml>[1], ledger).html
|
|
71
|
+
expect(html).toContain(`data-claim-kind="${kind}"`)
|
|
72
|
+
expect(check(html)).toEqual([])
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
})
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
|
|
3
|
+
import { SCHEMA_VERSION, normalizeManifest, validateOutcomeManifest, validateRepairState } from "./contracts.mjs"
|
|
4
|
+
|
|
5
|
+
function fourGateManifest() {
|
|
6
|
+
const manifest = sampleManifest()
|
|
7
|
+
const { fidelity: _dropped, ...gates } = manifest.gates
|
|
8
|
+
return { ...manifest, gates }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function sampleManifest() {
|
|
12
|
+
return {
|
|
13
|
+
schemaVersion: SCHEMA_VERSION,
|
|
14
|
+
sessionDir: "/tmp/session/20260101-120000",
|
|
15
|
+
startedAt: "2026-01-01T12:00:00.000Z",
|
|
16
|
+
finishedAt: null,
|
|
17
|
+
elapsedMinutes: null,
|
|
18
|
+
lane: "no-format",
|
|
19
|
+
interview: null,
|
|
20
|
+
deliverables: [
|
|
21
|
+
{ format: "pdf", status: "pending", promised: true, updatedAt: "2026-01-01T12:00:00.000Z" },
|
|
22
|
+
],
|
|
23
|
+
renders: [],
|
|
24
|
+
gates: { static: "not_run", fidelity: "not_run", layout: "not_run", visual: "not_run", proofread: "not_run" },
|
|
25
|
+
residualDefects: [],
|
|
26
|
+
repair: null,
|
|
27
|
+
sources: null,
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe("validateOutcomeManifest", () => {
|
|
32
|
+
test("#given an empty object #when validated #then it fails naming schemaVersion", () => {
|
|
33
|
+
const result = validateOutcomeManifest({})
|
|
34
|
+
expect(result.ok).toBe(false)
|
|
35
|
+
expect(result.errors.some((e) => e.includes("schemaVersion"))).toBe(true)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test("#given a well-formed manifest #when validated #then it passes", () => {
|
|
39
|
+
expect(validateOutcomeManifest(sampleManifest())).toEqual({ ok: true, errors: [] })
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test("#given a deliverable with an unknown status #when validated #then the error names the row", () => {
|
|
43
|
+
const m = sampleManifest()
|
|
44
|
+
m.deliverables[0].status = "done"
|
|
45
|
+
const result = validateOutcomeManifest(m)
|
|
46
|
+
expect(result.ok).toBe(false)
|
|
47
|
+
expect(result.errors.join("\n")).toMatch(/deliverables\[0\]\.status/)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test("#given a manifest written before the fidelity gate #when validated raw and after normalizeManifest #then only the normalized copy passes, with fidelity not_run", () => {
|
|
51
|
+
const old = fourGateManifest()
|
|
52
|
+
expect(validateOutcomeManifest(old).ok).toBe(false)
|
|
53
|
+
const normalized = normalizeManifest(old)
|
|
54
|
+
expect(normalized.gates.fidelity).toBe("not_run")
|
|
55
|
+
expect(normalized.gates.static).toBe("not_run")
|
|
56
|
+
expect(validateOutcomeManifest(normalized)).toEqual({ ok: true, errors: [] })
|
|
57
|
+
expect(old.gates).not.toHaveProperty("fidelity")
|
|
58
|
+
const failed = { ...old, gates: { ...old.gates, visual: "fail" } }
|
|
59
|
+
expect(normalizeManifest(failed).gates.visual).toBe("fail")
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test("#given a gate with an unknown value #when validated #then it fails", () => {
|
|
63
|
+
const m = sampleManifest()
|
|
64
|
+
m.gates.static = "ok"
|
|
65
|
+
expect(validateOutcomeManifest(m).ok).toBe(false)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe("validateRepairState", () => {
|
|
70
|
+
test("#given a well-formed state #when validated #then it passes, and a bad measure fails", () => {
|
|
71
|
+
const good = {
|
|
72
|
+
schemaVersion: SCHEMA_VERSION,
|
|
73
|
+
startedAt: "2026-01-01T12:00:00.000Z",
|
|
74
|
+
budget: { maxAttempts: 3, plateauLimit: 2, wallClockMs: 900_000 },
|
|
75
|
+
attempts: [{ at: "2026-01-01T12:01:00.000Z", measure: [1, 2, 0], signature: "em_dash_in_prose|unsourced_number" }],
|
|
76
|
+
consecutiveNonProgress: 0,
|
|
77
|
+
seenSignatures: ["em_dash_in_prose|unsourced_number"],
|
|
78
|
+
}
|
|
79
|
+
expect(validateRepairState(good)).toEqual({ ok: true, errors: [] })
|
|
80
|
+
const bad = { ...good, attempts: [{ at: "x", measure: [1, 2], signature: "" }] }
|
|
81
|
+
expect(validateRepairState(bad).ok).toBe(false)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
@@ -31,7 +31,7 @@ export const DEFECT_CODES = deepFreeze({
|
|
|
31
31
|
en_dash_in_prose: { severity: "minor", integrity: false, hint: "Use a hyphen for compounds; keep the en dash only between numbers." },
|
|
32
32
|
heading_too_long: { severity: "minor", integrity: false, hint: "Shorten the heading to one line (26 Korean characters or 12 English words)." },
|
|
33
33
|
heading_generic: { severity: "minor", integrity: false, hint: "Make the heading carry the section's claim instead of a generic label." },
|
|
34
|
-
unsourced_number: { severity: "major", integrity: false, hint: "Tag the number MEASURED / ASSUMED / DERIVED or cite its source in the same paragraph." },
|
|
34
|
+
unsourced_number: { severity: "major", integrity: false, hint: "Tag the number MEASURED / ASSUMED / DERIVED or cite its source in the same paragraph; under Sources only citation-field numbers and names (a hash, #12, GPT-4, Q3, 10-Q) are exempt, so quote a reference title that carries a code or a figure, or wrap it in <cite>: an unquoted one is checked, and 10-K / 8-K stay numerals because K is a multiplier. A slashed N/M reads as a month/day, so a fraction or a score (2/3, 7/12) under Sources is not checked (#11386): write it as a percent or tag it." },
|
|
35
35
|
chart_without_figure: { severity: "major", integrity: false, hint: "Wrap the image or chart in a figure container with a caption." },
|
|
36
36
|
chart_svg_no_text: { severity: "major", integrity: false, hint: "Give the chart a title, axis labels, units, and value labels as SVG text." },
|
|
37
37
|
chart_svg_missing_labels: { severity: "minor", integrity: false, hint: "Add the missing title, axis ticks, or unit label to the chart." },
|
|
@@ -58,12 +58,14 @@ export const DEFECT_CODES = deepFreeze({
|
|
|
58
58
|
pointer_label_mismatch: { severity: "blocker", integrity: true, hint: "The placeholder's label is not the row's label; check the id, then the label." },
|
|
59
59
|
quote_anchor_unresolved: { severity: "blocker", integrity: true, hint: "A from or to anchor is missing or occurs more than once in the quote; pick unique anchor words." },
|
|
60
60
|
unit_duplicated: { severity: "blocker", integrity: true, hint: "The unit after the placeholder repeats the row's unit; use :value or remove the unit." },
|
|
61
|
+
conversion_altered_number: { severity: "blocker", integrity: true, hint: "The source conversion altered this number (sources/S<n>/conversion.json lists it); snapshot a verified text of the source over it with `source snapshot --id S<n> --text <verified.txt> --replace` (refused while an active row cites S<n>; then retract those rows or use a new id), then re-add the fact." },
|
|
61
62
|
polish_diff_fail: { severity: "blocker", integrity: true, hint: "The polish pass changed numbers, tickers, table rows, claim ids, markup, or hidden content; revert to the pre-polish artifact and apply the language fixes only." },
|
|
62
63
|
fidelity_interview_incomplete: { severity: "blocker", integrity: true, hint: "A fidelity field is pending or missing in brief.md; answer the open question or record its default, then rerun." },
|
|
63
64
|
derived_not_allowed: { severity: "blocker", integrity: true, hint: "The brief allows no derived or assumed numbers; cite a source row directly or change the brief with the requester." },
|
|
64
65
|
source_outside_floor: { severity: "blocker", integrity: true, hint: "The row's source is outside the source floor the brief records; use a source the brief allows or remove the fact." },
|
|
65
66
|
brief_changed: { severity: "blocker", integrity: true, hint: "The edition's fill map was not written under the current ## Fidelity block (it changed after fill, or the map predates the binding); re-run fact fill, then fact verify." },
|
|
66
|
-
snapshot_hash_mismatch: { severity: "blocker", integrity: true, hint: "The source snapshot changed after it was pinned;
|
|
67
|
+
snapshot_hash_mismatch: { severity: "blocker", integrity: true, hint: "The source snapshot changed after it was pinned or cannot be read; restore it, or run source refresh to re-anchor its rows." },
|
|
68
|
+
snapshot_not_raw: { severity: "blocker", integrity: true, hint: "Measured rows need the original bytes: snapshot the source with --url, --html, or --raw <bytes> --text <extraction>; converted-only sources support warned quotations only." },
|
|
67
69
|
chart_value_untraceable: { severity: "blocker", integrity: true, hint: "A chart value, tick, or data file does not match its ledger-backed data source; re-render the chart from the exported data." },
|
|
68
70
|
quote_unbound: { severity: "blocker", integrity: true, hint: "A direct quotation has no ledger quote row; register it with fact quote and insert it through its placeholder." },
|
|
69
71
|
edition_unverified: { severity: "blocker", integrity: true, hint: "The delivered file has no matching fact verify record; run fact verify on that edition and record it with --verified-by." },
|
|
@@ -82,13 +84,18 @@ export const DEFECT_CODES = deepFreeze({
|
|
|
82
84
|
polish_hedging_decreased: { severity: "major", integrity: false, hint: "The polish pass removed qualifiers; restore them." },
|
|
83
85
|
polish_text_churn: { severity: "major", integrity: false, hint: "More than half the text changed during polish; the pass composed instead of proofreading." },
|
|
84
86
|
snapshot_mismatch: { severity: "major", integrity: false, hint: "The operands come from different collection windows; use rows from one window or state the windows separately." },
|
|
87
|
+
operand_timestamp_missing: { severity: "major", integrity: false, hint: "Record the operand's observed_at timestamp before checking its collection window." },
|
|
88
|
+
operand_missing: { severity: "major", integrity: false, hint: "A windowed operation names an operand that is not in the fact ledger; restore the row or re-derive from existing rows." },
|
|
85
89
|
join_integrity_fail: { severity: "major", integrity: false, hint: "A table row combines facts from different source observations; keep each row to one observation or split it." },
|
|
86
90
|
quote_stale_version: { severity: "major", integrity: false, hint: "The quoted source revision differs from the revision the report targets; re-snapshot the target revision or date the quote." },
|
|
87
91
|
quote_fuzzy_match: { severity: "minor", integrity: false, hint: "The source text is OCR-noisy; confirm the snapshot and prefer the raw document." },
|
|
92
|
+
relocated: { severity: "minor", integrity: false, hint: "After source refresh the exact quote and context sit at one new byte range; review the old and new offsets (verification never rewrites the row)." },
|
|
93
|
+
quote_converted_only: { severity: "minor", integrity: false, hint: "The quote comes from a converted-only source with no raw bytes; re-snapshot the original with --raw and --text, or keep the warned quote." },
|
|
88
94
|
name_outside_quote: { severity: "minor", integrity: false, hint: "A name in the sentence is not in the cited quote; add the source or remove the name." },
|
|
89
95
|
verification_claim_unmarked: { severity: "minor", integrity: false, hint: "The sentence reads as a check we ran but carries no verified mark; mark it {{V:F<n>:label}} on a recorded command-output row, or reword it." },
|
|
90
96
|
scope_widened_warn: { severity: "minor", integrity: false, hint: "The sentence uses a broader scope word than the quote; confirm the scope or narrow it." },
|
|
91
97
|
particle_unverified: { severity: "minor", integrity: false, hint: "The particle after this value could not be checked; read it aloud and fix it by hand if wrong." },
|
|
98
|
+
unit_unbound: { severity: "minor", integrity: false, hint: "Use the full fact placeholder, or write the unit right after :value (with or without a space; a Korean particle may follow), as its :unit element, or in the matching table column header." },
|
|
92
99
|
fallback_without_entity: { severity: "minor", integrity: false, hint: "The replacement quote has no entity for attribution; set one on the row." },
|
|
93
100
|
meaning_drift_warn: { severity: "minor", integrity: false, hint: "A separate reader found the sentence changes scope, subject, or certainty; rewrite from the quote." },
|
|
94
101
|
polish_edit_unlocated: { severity: "minor", integrity: false, hint: "The edit's before-text was not found exactly once; re-propose against the current text." },
|
|
@@ -98,15 +105,17 @@ export const DEFECT_CODES = deepFreeze({
|
|
|
98
105
|
|
|
99
106
|
/** Codes only the fidelity verifier raises (fact ledger, fill, verify, meaning, polish). */
|
|
100
107
|
export const FIDELITY_CODES = Object.freeze([
|
|
108
|
+
"unit_unbound",
|
|
101
109
|
"unresolved_placeholder", "value_mismatch", "unit_mismatch", "quote_not_verbatim", "claim_status_invalid",
|
|
102
110
|
"incompatible_operands", "pointer_label_mismatch", "quote_anchor_unresolved", "unit_duplicated", "polish_diff_fail",
|
|
103
111
|
"fidelity_interview_incomplete", "derived_not_allowed", "source_outside_floor", "brief_changed", "snapshot_hash_mismatch",
|
|
112
|
+
"conversion_altered_number",
|
|
104
113
|
"chart_value_untraceable", "quote_unbound", "edition_unverified", "untraceable_number", "unsupported_verification", "claim_kind_mismatch",
|
|
105
114
|
"conflicting_readings", "hedge_dropped", "direction_flipped", "causality_added", "qualifier_dropped", "unbound_sentence",
|
|
106
115
|
"meaning_drift_confirmed", "meaning_unverified", "polish_edit_rejected", "polish_hedging_decreased", "polish_text_churn", "snapshot_mismatch",
|
|
107
|
-
"join_integrity_fail", "quote_stale_version", "quote_fuzzy_match", "name_outside_quote", "verification_claim_unmarked", "scope_widened_warn",
|
|
116
|
+
"operand_timestamp_missing", "operand_missing", "join_integrity_fail", "quote_stale_version", "quote_fuzzy_match", "name_outside_quote", "verification_claim_unmarked", "scope_widened_warn",
|
|
108
117
|
"particle_unverified", "fallback_without_entity", "meaning_drift_warn", "polish_edit_unlocated", "polish_link_changed",
|
|
109
|
-
"polish_name_changed",
|
|
118
|
+
"polish_name_changed", "snapshot_not_raw", "relocated", "quote_converted_only",
|
|
110
119
|
])
|
|
111
120
|
const FIDELITY_SET = new Set(FIDELITY_CODES)
|
|
112
121
|
|