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
|
@@ -50,7 +50,7 @@ Always required, never null: `fact_id`, `kind`, `raw` (string), `quote` (string)
|
|
|
50
50
|
| `snapshot_sha256` | sha256 | sha256 | sha256 or null | sha256 or null | sha256 or null |
|
|
51
51
|
| `rationale` | string or null | string or null | string or null | non-empty | string or null |
|
|
52
52
|
| `exact` | from `value` | null | reduced rational | rational or null | reduced rational |
|
|
53
|
-
| `context` | null | null | written by derive (object or null) | null | written by derive (object or null) |
|
|
53
|
+
| `context` | quote context or null (legacy) | quote context or null (legacy) | written by derive (object or null) | null | written by derive (object or null) |
|
|
54
54
|
| `operation` | null | null | sum/diff/growth/share/ratio/expr | null | `convert` |
|
|
55
55
|
| `precision` | null | null | `{ places, sigfigs }` | null | `{ places, sigfigs }` |
|
|
56
56
|
| `compatibility` | null | null | checked or unchecked (expr) | null | checked or unchecked (expr) |
|
|
@@ -61,8 +61,12 @@ Always required, never null: `fact_id`, `kind`, `raw` (string), `quote` (string)
|
|
|
61
61
|
it when the caller leaves it null. Derived and converted rows get it from
|
|
62
62
|
derive (plan todo 9): a converted value's rational comes from the original and the factor,
|
|
63
63
|
not from the rounded `value`, so `addRow` never computes it from `value`.
|
|
64
|
-
- `locator` is `{ artifact, char_start <= char_end, page?, line?, table?, row_label?,
|
|
65
|
-
col_label? }
|
|
64
|
+
- `locator` is `{ artifact, char_start <= char_end, unit?, page?, line?, table?, row_label?,
|
|
65
|
+
col_label? }`: `char_start/char_end` are a half-open byte range of `artifact` (raw.bin, or
|
|
66
|
+
text.txt for a declared or converted extraction) in its own encoding; new rows write
|
|
67
|
+
`unit: "bytes"`. No unit marks a legacy text locator.
|
|
68
|
+
- Source `snapshot_sha256` binds the pinned body exactly (raw.bin; text.txt for converted-only). Source `context` is `{prefix, suffix}`, each
|
|
69
|
+
at most 32 Unicode characters copied around the value span, or the whole quote for Q rows.
|
|
66
70
|
- All other fields are nullable with the types in `fact-ledger-schema.mjs`.
|
|
67
71
|
|
|
68
72
|
Exact rational integer strings are canonical: no leading zeros, negative zero, negative denominator,
|
|
@@ -8,17 +8,46 @@ Every command is `node "$SKILL_DIR/scripts/report-tools.mjs" <command> --session
|
|
|
8
8
|
|
|
9
9
|
| Path | Written by | Holds |
|
|
10
10
|
| --- | --- | --- |
|
|
11
|
-
| `sources/S<n>/
|
|
12
|
-
| `sources/S<n>/
|
|
13
|
-
| `sources/S<n>/
|
|
11
|
+
| `sources/S<n>/raw.bin` | `source snapshot`, `source refresh` | bytes exactly as fetched or captured (absent only for a converted-only source); `snapshot_sha256` is sha256 of this file |
|
|
12
|
+
| `sources/S<n>/text.txt` | `source snapshot`, `source refresh` | the locator text (below): the visible text of a page, the decoded bytes of a document, or a declared or converted extraction; one line per block, pages joined by a form feed |
|
|
13
|
+
| `sources/S<n>/source.html` | `source snapshot` (page sources) | the captured page decoded to UTF-8, a reading aid; locators never read it |
|
|
14
|
+
| `sources/S<n>/meta.json` | `source snapshot`, `source refresh` | `source_id`, `url`, `observed_at`, `sha256`, `extractor`, `revision`, `kind`, `provenance`, `text_source`, `charset`, and `text_sha256` for a declared extraction |
|
|
14
15
|
| `sources/S<n>/sentences.jsonl`, `acronyms.json` | `source snapshot` | the sentence index (`S<n>:s<k>`) and the acronym table the fidelity gate reads |
|
|
15
16
|
| `sources/S<n>/command.json` | `source snapshot --command` | argv, working directory, exit status, stdout and stderr hashes |
|
|
16
17
|
| `fact-ledger.json` | `fact add`, `fact quote`, `fact derive`, `fact retract` | `{ schemaVersion: 1, rows, events }` |
|
|
17
18
|
| `claims.json` | `claims index` | the claim table and the `verified-claims` membership |
|
|
18
19
|
| `fidelity-defects.json` | `fact verify` | the verify record: the fidelity envelope (`record_kind: "fidelity"`, `artifact_sha256`, `report`, `written_at`, `defects`) plus `command`, `status`, `exitCode`, `format`, `counts`, `gatesRun` |
|
|
19
|
-
| `fidelity-meaning-defects
|
|
20
|
+
| `fidelity-meaning-defects.<format>.json` | `fact meaning-check --edition <format>` | one delivered edition's meaning record (without `--edition`, the legacy session record `fidelity-meaning-defects.json`): the fidelity envelope (`record_kind: "meaning"`) plus the run fields under Meaning verdicts |
|
|
20
21
|
|
|
21
|
-
A source directory is immutable. Snapshotting the same id
|
|
22
|
+
A source directory is immutable. Snapshotting the same id with the same raw bytes is a no-op; different bytes fail with `snapshot_exists`, because rows pin the snapshot hash; `source refresh` (below) is the one explicit repin. `source snapshot --replace` swaps in a corrected capture under the same id only while no active row cites it (otherwise `snapshot_pinned`, listing the rows); the replacement drops the old `command.json`, and `source.html` and `conversion.json` follow the new capture. A `--text <verified.txt> --replace` over a source that has `raw.bin` keeps those bytes and records the verified text as their declared extraction (`text_source: declared`, measurable, `locator.artifact` `text.txt`); plain `--text` without `--replace` stays converted-only.
|
|
23
|
+
|
|
24
|
+
Page snapshotting (`--url`, `--html`, or an HTML `--raw`) probes its conversion to the locator text and writes `sources/S<n>/conversion.json` through `writeFidelityRecord` (the `source_conversion` envelope with `conversion_altered_numbers`, `lost`, `raw_count`, `converted_count`); `source snapshot` prints the altered list. `fact add` and `fact quote` refuse a located value, or a number in its sentence, that the list names (`conversion_altered_number`, no row written): write a verified text of the source, run `source snapshot --id S<n> --text <verified.txt> --replace`, and add from it. Numbers are compared with one grouped-number grammar (a 1-3 digit lead, 3-digit groups with one separator type, no digit after the last group; a lone period group such as `1.234` is a decimal). A cell, row, list-item, block or line break never joins digits, digits from a link target, image source, alt text or title cover a converted number only inside Markdown link or image syntax, a converter's line-start list marker (`1. `, `2) `, `(3) `) is exempt only when the source has an `<ol>` item with that number and the markers do not outnumber the `<ol>` items (lazy `1. 1. 1.` numbering passes), a numeric reference label (`[x][1]` with its `[1]: url`) is link syntax, a footnote definition (`[^1]: text`) exempts only its label and its text stays prose, and a space-grouped number a hard wrap split over one line break is read whole when the source holds it whole and not both halves (raw `12 345 and 12 and 345` wrapped inside `12 345` reports both halves). A `-` or U+2212 after a single letter (`x-5`) or an exponent (`1e-5`) is a sign; after an identifier such as `cite_note-7` or `UTF-8` it is not. Markdown markup never decides a sign: emphasis, code, strike, link or image closers before a dash are skipped, read with the CommonMark inline grammar (titles, parentheses inside a target, reference endings and backslash-escaped closers included: `**2019**-2023` and `[1990](/wiki/1990 "1990")-2000` are ranges, `*UTF*-8` an identifier), and an opener between a sign and its digits (`-**5**`) keeps the sign. Named character references (`−`, ` `, ` `) are decoded on both sides with one table, so a verbatim copy probes clean. Raw inline HTML a converter leaves in its Markdown (pandoc's gfm writer keeps `<sup>`, `<sub>`, sized `<img>`, `<span>`, `<br>`) is read with the same tag reader as the raw side: `<sup>`, `<sub>` and break tags are boundaries, any other tag or comment is dropped with its attributes. A reference definition's title may sit alone on the next line. `source probe-conversion <raw-file> <converted-file>` runs the same probe on your own conversion; `lost` is a warning only.
|
|
25
|
+
|
|
26
|
+
### Conversion probe scope
|
|
27
|
+
|
|
28
|
+
The probe guarantees these converter outputs: CommonMark links and images (inline, reference and autolink forms, titles, balanced parentheses, backslash escapes), emphasis, strike, code spans and lists; the tag set the html-lite tokenizer reads (`<sup>`, `<sub>`, the block and break tags as boundaries, every other tag and comment dropped); and the named-entity table in `scripts/entities.mjs` plus decimal and hex numeric references. A number the converter left unchanged inside this scope is not reported as altered.
|
|
29
|
+
|
|
30
|
+
#### Declared out of scope
|
|
31
|
+
|
|
32
|
+
- Custom converter syntaxes: shortcodes (`{{< figure src="chart-2019.png" >}}`), attribute blocks (`{width=640}`).
|
|
33
|
+
- MathJax and LaTeX (`$\frac{3}{4}$`, `\(\sqrt[3]{8}\)`).
|
|
34
|
+
- Non-CommonMark tables: AsciiDoc table attributes (`[cols="1,3"]`), and a spanning cell repeated once per column.
|
|
35
|
+
- Footnote extensions beyond pandoc's, such as numbered back-reference titles (`"Jump back to footnote 2 in the text"`).
|
|
36
|
+
- A reference definition whose destination sits on the next line, a legacy reference without its semicolon (` `), a numeric reference padded past 6 hex or 7 decimal digits, and a converter that writes the text's `&` unescaped where it spells a reference.
|
|
37
|
+
|
|
38
|
+
Anything outside the guaranteed scope gets no allowance: every digit such a construct adds or reshapes is reported as altered (the safe direction: `fact add` refuses the number, it is never silently accepted). Recover with a verified text: `source snapshot --id S<n> --text <verified.txt> --replace`, then add from it. The probe's class table in the source repository has a row per example above that asserts the altered report, so the boundary is tested.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Snapshot and locator contract
|
|
42
|
+
|
|
43
|
+
This is the one definition; `SKILL.md` and the collection reference point here.
|
|
44
|
+
|
|
45
|
+
- **Raw means the captured bytes** of what the run fetched: the page HTML (`--url`, `--html`), a saved file (`--raw <file>`), a PDF, or a command's stdout (`--command`). `snapshot_sha256` is sha256 of `raw.bin`.
|
|
46
|
+
- **A `--text` file is never raw.** `source snapshot --text <file>` alone registers a converted-only source (`kind: converted-only`, no `raw.bin`): `fact add` on it fails with `snapshot_not_raw`, and `fact quote` works but every quote carries the minor `quote_converted_only` warning (printed by `fact quote` with or without `--json`, and reported again by `fact verify`). `--raw <bytes> --text <extraction> --extractor NAME@VERSION` keeps the original bytes and declares the text their extraction (a PDF and its `pdftotext` output); `raw.bin` and `text.txt` are then both pinned (`sha256`, `text_sha256`). An HTML `--raw` file is read as a page, so the text only names the extractor. `--raw` with `--url`, `--html`, or `--command` is a usage error.
|
|
47
|
+
- **Locators match the reader-visible text, never markup.** For a page, the locator text is its text nodes in reading order: attribute values, CSS, `<head>`, `<script>`, `<style>`, `<svg>`, `<noscript>`, `<template>`, code-like elements, and anything hidden from every reader contribute nothing, so a number there can never be located or quoted. Hidden means `aria-hidden="true"`, the `hidden` attribute (not `hidden="until-found"`), a closed `<dialog>`, `display:none` or `content-visibility:hidden` (with their descendants), and `visibility:hidden` or `collapse` (inherited until a descendant sets `visibility:visible`), as set by an inline style or by a rule in the page's own `<style>` elements; `opacity:0`, clipping, zero size, off-screen positioning and text color do not hide. A rule hides only when it applies under every condition: its selector is one tag name, one `.class` or one `#id` (class and id names match case-sensitively, tag names do not), it sits outside every at-rule other than `@layer` and `@media all`, and its `<style>` has no `media` other than `all`. Conditional at-rules (`@media`, `@supports`, `@container`, `@scope`, `@starting-style`) are not applied as hiding rules, and external stylesheets, scripts and compound selectors are not evaluated, so text they hide still counts as visible; a conditional or compound rule that would show the element again under the cascade (importance, inline style, layer, specificity, order) keeps its text visible, since some reader sees it. A quote may span inline markup (`opens <em>no earlier</em> than 2027`), and an unclosed element ends at its block, never at the end of the document. `sentences.jsonl` indexes the same text, so a row's `sentence_id` names its sentence there.
|
|
48
|
+
- **Offsets are bytes of the artifact, in its own encoding.** `locator.artifact` is `raw.bin` (pages and documents) or `text.txt` (declared and converted extractions), `locator.unit` is `bytes`, and `char_start/char_end` are a half-open byte range of that file: the decoded text keeps a map back to the raw bytes (charset from a BOM, `--charset` or the HTTP header, then a `<meta charset>`; UTF-8 by default), so Latin-1 or EUC-KR pages are counted in their own bytes, never through a re-encode. `value_span` is in UTF-16 code units of `quote`. A row without `unit` is a legacy locator into `text.txt`.
|
|
49
|
+
- **Verification fails closed.** `fact verify` reads every snapshot a cited row rests on; when the sources directory, `meta.json`, `raw.bin`, or `text.txt` cannot be read, each such row gets the blocking `snapshot_hash_mismatch` naming the cause (`ENOENT`, `EACCES`, invalid metadata), the verify record is still written, and rows on healthy sources are checked as usual.
|
|
50
|
+
- **Sessions from before this contract** (rows without `locator.unit: "bytes"`) keep verifying against their pinned `text.txt`, but `fact add` refuses their legacy snapshots: snapshot the source again under a new id to add rows.
|
|
22
51
|
|
|
23
52
|
## Row fields
|
|
24
53
|
|
|
@@ -31,7 +60,8 @@ A source directory is immutable. Snapshotting the same id again with the same te
|
|
|
31
60
|
| `raw`, `quote`, `value_span` | the source's own characters for the value, the whole containing sentence or cell, and where `raw` sits inside `quote` |
|
|
32
61
|
| `qualifier` | a bounding word the source puts on the value: `upper_inclusive` (up to, at most), `lower_inclusive` (at least), `approximate` (about), `near` (nearly), `lower_exclusive` (over, more than), `upper_exclusive` (under, less than) |
|
|
33
62
|
| `source_id`, `snapshot_sha256`, `sentence_id` | the snapshot the row was read from, its hash at that moment, and the sentence id |
|
|
34
|
-
| `locator` | where `quote` sits
|
|
63
|
+
| `locator` | where `quote` sits: `artifact` (`raw.bin` or `text.txt`), `unit: "bytes"`, and `char_start/char_end`, a half-open byte range of that artifact (see the contract above); absent unit identifies a legacy row. Also `line`, `page`, table labels, `source_kind`, `url`, `host`, and `pointed` |
|
|
64
|
+
| `context` | source rows: `{prefix, suffix}`, up to 32 Unicode characters each around the value span (around the whole quote for quote rows), copied before normalization; null on legacy rows |
|
|
35
65
|
| `extracted_by` | the snapshot's extractor: `tool:source-snapshot@1` (fetched or executed by the script), `model` (a capture the browser lane imported; lower trust), or `extractor:<name>@<version>`; `fact-derive` for a derivation |
|
|
36
66
|
| `observed_at`, `valid_at` | when the row was registered, and the period the value describes (`--valid-at`) |
|
|
37
67
|
| `entity`, `population`, `accounting_basis`, `observation_id` | declarations the derivations check (`--entity`, `--population`, `--accounting-basis`, `--observation O<n>`) |
|
|
@@ -50,6 +80,10 @@ A source directory is immutable. Snapshotting the same id again with the same te
|
|
|
50
80
|
|
|
51
81
|
A locator that finds nothing returns `fact_not_located`, more than one candidate `fact_ambiguous`, and nothing is written. Read the printed row and its 60 characters of context on each side before using it; a wrong row is retracted, never edited.
|
|
52
82
|
|
|
83
|
+
`fact verify` rehashes each snapshot against its metadata and each cited row's pin; drift is `snapshot_hash_mismatch` even if the quote could relocate. Verification never rewrites the ledger or silently repins a hash.
|
|
84
|
+
|
|
85
|
+
`source refresh S<n>` is the explicit repin: it re-fetches the source's URL (or reads the new capture given with the `source snapshot` input flags), replaces the snapshot, and re-anchors every active byte-located row on that source by its exact quote plus its stored context. A row found exactly once gets the new `snapshot_sha256` and keeps its old locator, so `fact verify` then reports the minor `relocated` with the old and new byte offsets; a row whose quote is gone, or found more than once with the same context, keeps its old pin, is reported as `quote_not_verbatim`, and stays a `snapshot_hash_mismatch` blocker until it is retracted or added again (exit 1).
|
|
86
|
+
|
|
53
87
|
## Meaning verdicts
|
|
54
88
|
|
|
55
89
|
`ingestVerdicts(pairs, verdictFiles, options)` (`scripts/meaning-check.mjs`) folds the meaning readers' verdict files over the pairs of `extractPairs` and returns four lists:
|
|
@@ -63,7 +97,7 @@ A locator that finds nothing returns `fact_not_located`, more than one candidate
|
|
|
63
97
|
|
|
64
98
|
Coverage is fail-closed. A consumer treats a non-empty `unverified` list as blocking: those pairs were never read, so an empty `defects` list does not mean the report is clean. An unreadable verdict path or invalid JSON raises a `TypeError` naming the file, which the CLI maps to exit code 2.
|
|
65
99
|
|
|
66
|
-
`fact meaning-check` writes these lists into `fidelity-meaning-defects.json` through the one fidelity record writer (`writeFidelityRecord` in `scripts/fidelity-records.mjs`). The record is the envelope every fidelity record carries, `record_kind` (`meaning`), `artifact_sha256` and `report` (copied from `pairs.json`, so the record names the edition the readers judged), `written_at`, and `defects` (the folded defects plus one `meaning_unverified` per unread pair), followed by the run fields `command`, `status`, `exitCode`, `run_id`, `pairs_sha256`, `counts`, `dropped`, `unverified`, `calibration_path`, `calibration_written`, `calibration_replaced`, and `promotion_eligibility`. Any other field makes the record malformed. A pairs file without `artifact_sha256` and `report` exits 2 before anything is written. The delivery barrier
|
|
100
|
+
`fact meaning-check` writes these lists into the edition's meaning record (`fidelity-meaning-defects.<format>.json` with `--edition <format>`, else `fidelity-meaning-defects.json`) through the one fidelity record writer (`writeFidelityRecord` in `scripts/fidelity-records.mjs`). The record is the envelope every fidelity record carries, `record_kind` (`meaning`), `artifact_sha256` and `report` (copied from `pairs.json`, so the record names the edition the readers judged), `written_at`, and `defects` (the folded defects plus one `meaning_unverified` per unread pair), followed by the run fields `command`, `status`, `exitCode`, `run_id`, `pairs_sha256`, `counts`, `dropped`, `unverified`, `calibration_path`, `calibration_written`, `calibration_replaced`, and `promotion_eligibility`. Any other field makes the record malformed. A pairs file without `artifact_sha256` and `report` exits 2 before anything is written. The delivery barrier binds each delivered edition to its own record (else any edition meaning record for the same bytes, else the legacy file) and refuses that edition when its source bytes do not hash to the record's `artifact_sha256`, so a rewrite needs a fresh `fact pairs` and reader run for that edition.
|
|
67
101
|
|
|
68
102
|
## Operations
|
|
69
103
|
|
|
@@ -72,7 +106,7 @@ Coverage is fail-closed. A consumer treats a non-empty `unverified` list as bloc
|
|
|
72
106
|
- `fact derive --op <sum|diff|growth|ratio|share|convert|expr> ...` computes a new row from active rows and prints its id; the placeholder uses that id. Operands go by position for sum, diff, and convert (`--to <unit>`), as `--from/--to`, `--part/--whole`, or `--num/--den` for growth, share, and ratio, and as one formula argument for expr. Every op except convert declares its result unit with `--unit <unit>` (`--unit null` for dimensionless); a `%` sum also needs `--disjoint --reference <denominator> --rationale <why>`. The unit rules are in `unit-rules.md`.
|
|
73
107
|
- `fact retract <id> --reason <why>` retires a row; `--replacement <id>` marks it superseded by another active row. Rows that depend on a retired row fail at fill time.
|
|
74
108
|
- `fact export --csv --out <file>` writes `fact_id,label,plot_value,unit` for every active value row: the only data a chart may plot.
|
|
75
|
-
- `fact fill <src> --out <file>` renders every placeholder from the ledger; `fact verify <file>` checks the
|
|
109
|
+
- `fact fill <src> --out <file>` renders every placeholder from the ledger; `fact verify <file>` checks the edition against the ledger, snapshots, and claim index. A `:value` placeholder keeps its unit in metadata: verify checks the unit written right after the value (with or without a space, a Korean particle allowed: `{{F1:span_len:value}} m`, `{{F3:rate_yoy:value}}%`), a currency sign right before it, its `:unit` element, and the header of its visual table column. The unit after the value is read through inline markup, line breaks and parentheses (`{{F1:span_len:value}} <b>m</b>`, `{{F1:span_len:value}}<br>m`, `{{F1:span_len:value}} (m)`), with a Korean particle or qualifier glued on; a qualifier word on its own (the Korean qualifiers such as chogwa "over" or jeongdo "about", or `or more`) is never read as a unit, and an English unit alias that is also an ordinary word (`won`, `second`, `pound`) counts only as the row's own unit or beside a currency sign or column header of its kind (`$320 pounds` blocks). The longest unit the words after the value spell is the one read, so a longer unit that starts with the row's unit is never taken for it (`12 % p`, `12 percent points` and the spaced Korean percent-point spellings are `%p`, not `%`); English words join only as a spaced alias (`percentage points`), so `m in` stays `m`. Fill records the mode and the unit bound to each value (after it, as its currency sign, or in its column header) in the fill map as `unit_bound`, and verify reads that map for HTML too, so deleting `data-fact-mode`, or replacing or deleting a bound unit, still blocks. A conflicting unit blocks with `unit_mismatch`; no recognizable unit warns with `unit_unbound`. `outcome set <format> delivered` records intent; `outcome verify` and `outcome finish` enforce delivery.
|
|
76
110
|
- `fact pairs <file>` writes `pairs.json` for the meaning readers; `fact meaning-check --pairs pairs.json --verdicts <file> ...` ingests their verdicts.
|
|
77
111
|
|
|
78
112
|
## Meaning command
|
|
@@ -11,7 +11,7 @@ A `verified` claim is satisfied only when the cited row itself has a locator art
|
|
|
11
11
|
|---|---|---|---|---|---|---|---|
|
|
12
12
|
| `fact` | `{{F12:label}}` | none (or `data-claim-kind="fact"`) | `measured`, `converted`, `derived` | any | `claim_kind_mismatch` | none | Accepts exactly what an unmarked numeral accepts, so marking fact is never stricter than not marking. Neither accepts an `assumed` row: an unmarked assumption reads as a fact, so it needs its `{{A:F12:label}}` mark (`claim_kind_mismatch` otherwise). |
|
|
13
13
|
| `quote` | `{{Q7:label}}` | none (or `data-claim-kind="quote"`) | `quote` | any | `claim_kind_mismatch` | none | - |
|
|
14
|
-
| `verified` | `{{V:F12:label}}` | `data-claim-kind="verified"` | `measured`, `quote` | `command` | `unsupported_verification` | `verification_claim_unmarked` on a first-person run: we/I (have) ran, run, executed, verified by (not ran out of)
|
|
14
|
+
| `verified` | `{{V:F12:label}}` | `data-claim-kind="verified"` | `measured`, `quote` | `command` | `unsupported_verification` | `verification_claim_unmarked` on a first-person run: we/I (have) ran, run, re-ran, re-run, executed, verified by (not ran out of), or by running after we/our in the sentence; a first-person check: we/I (have) verified, checked, confirmed, measured, tested, double-checked, cross-checked (not checked in/into/out) with a result object in the clause (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, or a digit) and no document named before the clause ends (report, reports, filing, filings, document, documents, paper, papers, article, articles, publication, statement, disclosure, website, page, docs, documentation; a comma, a semicolon, or as, which, who, whom, whose, where 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 \uD655\uC778, \uAC80\uC99D, \uCE21\uC815, \uC810\uAC80 + \uD588, \uD558\uC600, \uD558\uC5EC, \uD574, \uD55C with a result object in the clause (\uACB0\uACFC, \uAC12, \uC218\uCE58, \uAE38\uC774, \uD569\uACC4, \uBE44\uC728, \uC18D\uB3C4, \uC9C0\uD45C, \uB370\uC774\uD130, or a digit) and no document before the clause ends (\uBCF4\uACE0\uC11C, \uBB38\uC11C, \uACF5\uC2DC, \uB17C\uBB38, \uAE30\uC0AC, \uC790\uB8CC; a comma, a semicolon, or \uCC98\uB7FC, \uB4EF\uC774, \uAC19\uC774 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 | 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. |
|
|
15
15
|
| `derived` | `{{D:F12:label}}` | `data-claim-kind="derived"` | `derived`, `converted` | any | `claim_kind_mismatch` | none | - |
|
|
16
16
|
| `assumed` | `{{A:F12:label}}` | `data-claim-kind="assumed"` | `assumed` | any | `claim_kind_mismatch` | none | Numeric assumptions only (an assumed ledger row carries a decimal value); a qualitative assumption stays prose. |
|
|
17
17
|
<!-- claim-kinds:end -->
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Markdown block boundaries
|
|
2
|
+
|
|
3
|
+
The light Markdown model preserves the documented CommonMark paragraph interruption rule:
|
|
4
|
+
only an ordered marker numbered `1` interrupts an open paragraph. In
|
|
5
|
+
`1. a\ncontinued\n2. b`, the blocks remain a list item `a` and a paragraph
|
|
6
|
+
`continued\n2. b`. The model does not attach the unindented continuation to the
|
|
7
|
+
preceding list item. The `2` remains paragraph text with its original source
|
|
8
|
+
offset; fidelity numerals in either block remain available to the numeral parser.
|
|
9
|
+
|
|
10
|
+
A closing code fence permits at most three leading spaces. A candidate indented
|
|
11
|
+
four spaces stays code; without a later valid close the parser reports
|
|
12
|
+
`unterminated_fence` instead of exposing the code as report prose.
|
|
@@ -15,7 +15,7 @@ This reference catalogs every defect code the report gates (`static`, `fidelity`
|
|
|
15
15
|
| `en_dash_in_prose` | minor | false | En dashes (–) are used incorrectly outside of numeric ranges. Only numeric ranges (e.g., "pages 5–10") should use en dashes. | Use a hyphen for compounds; keep the en dash only between numbers. |
|
|
16
16
|
| `heading_too_long` | minor | false | A heading exceeds one visual line: 26 Korean characters (52 display width units) or 12 English words. | Shorten the heading to one line (26 Korean characters or 12 English words). |
|
|
17
17
|
| `heading_generic` | minor | false | A heading uses generic labels (e.g., "Introduction", "Background") without conveying the section's specific claim or finding. | Make the heading carry the section's claim instead of a generic label. |
|
|
18
|
-
| `unsourced_number` | major | false | A numeric value (percentage, count, duration, ratio) appears without
|
|
18
|
+
| `unsourced_number` | major | false | A numeric value (percentage, count, duration, ratio) appears without source attribution or lineage. Under Sources, an element is split at line breaks and sentence ends, and a sentence is checked exactly as under any other heading unless every numeral in it is a citation-field number: a year, a full date, or a month/day (`10/26`, `Oct 26`, `2026. 10. 26.`; a day count such as `30 days` is checked); a page, volume, issue, number, or edition marker; a number inside a URL, DOI, arXiv id, ISBN, or ISSN; a number inside a quoted title (straight or curly quotes, corner brackets, `<cite>`, or an `<i>`/`<em>` title directly before a URL or date); a number inside link text; or a citation tag's digits. A year range (`2019-2023`, `2019~2023`) is a date. A digit run glued to letters that are not a unit, multiplier, or currency is a name, not a numeral (a commit hash, `#123`, `GPT-4`, `v2.3.1`, `Q3`, `FY27`, `10-Q`), and so is a dotted version (`0.30.14`); `50M`, `10k`, `3x`, `x3`, `2.5GB`, `320m`, `12%`, `5mn`, `40pct`, `5yrs`, and the European grouping `1.234.567` stay numerals. A unit, multiplier, or percent on the right is read before the letters on the left, so a word glued in front of a measure (`rate40%`, or a Korean word written solid before `300` and a counter) keeps it a numeral; Latin letters on both sides make an identifier (`W3C`). A Korean ordinal (the je prefix, the jjae suffix, the cha counter) is a name and a Korean quarter (N bungi) is a date, like `Q3`; a two-digit dotted date (`26.10.26`) is a date. Ruling consequences: `10-K` and `8-K` stay numerals because `K` is a multiplier while `10-Q` is a name, so quote a title that carries a filing code; a slashed month/day also covers fractions (`2/3`) and table scores (`7/12`), which are therefore not checked under Sources (#11386). A version, figure, or count in an unquoted title (`Llama 3.1 model card`, `Buyback $94B`, `Revenue grew 40%`) is checked; quote the title to exempt it. | 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. |
|
|
19
19
|
| `chart_without_figure` | major | false | An image or chart lacks a figure wrapper with a caption. Uncaptioned charts isolate visuals from narrative flow. | Wrap the image or chart in a figure container with a caption. |
|
|
20
20
|
| `chart_svg_no_text` | major | false | An SVG chart or diagram lacks a title, axis labels, units, or value labels. Visuals cannot stand alone without text guidance. | Give the chart a title, axis labels, units, and value labels as SVG text. |
|
|
21
21
|
| `chart_svg_missing_labels` | minor | false | An SVG chart has some labels (e.g., title) but is missing others (e.g., axis ticks or unit). | Add the missing title, axis ticks, or unit label to the chart. |
|
|
@@ -37,22 +37,26 @@ Raised only by the fidelity verifier (the fact ledger, fill, verify, meaning, an
|
|
|
37
37
|
|------|----------|-----------|-----------------|-----------|
|
|
38
38
|
| `unresolved_placeholder` | blocker | true | A fact or quote placeholder is left in the artifact, names an unknown ledger id, is malformed, or uses an unsupported mode. | Register the fact with fact add or remove the sentence; a placeholder is never filled with a guess. |
|
|
39
39
|
| `value_mismatch` | blocker | true | A displayed value differs from its ledger row's rendering, or a stored derived value differs from exact recomputation (a hand edit after fill). | Re-run fact fill; never edit a filled value by hand. |
|
|
40
|
-
| `unit_mismatch` | blocker | true | A displayed, adjacent, or header unit conflicts with the ledger row's unit or scale. | Re-run fact fill, or derive a converted row with fact derive --op convert. |
|
|
40
|
+
| `unit_mismatch` | blocker | true | A displayed, adjacent, or header unit conflicts with the ledger row's unit or scale, or a value-mode fact lost the unit bound to it at fill (the fill map records it: the unit after the value, its currency sign, or its column header). | Re-run fact fill, or derive a converted row with fact derive --op convert. |
|
|
41
|
+
| `unit_unbound` | minor | false | A value-mode fact with a ledger unit shows no recognizable unit: none right after its value (with or without a space, a Korean particle allowed), no currency sign right before it, no :unit element after it, and no unit in its visual column header (a table with a rowspan or without a th row binds no header). | 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. |
|
|
41
42
|
| `quote_not_verbatim` | blocker | true | A quotation bound to a quote row does not match the source snapshot contiguously after normalization, or a rendered cut is not the registered cut. | Re-insert the quote through its {{Q<n>}} placeholder; after a second failure the sentence is replaced by the quote. |
|
|
42
43
|
| `claim_status_invalid` | blocker | true | A sentence's claim binding names an unknown claim, a refuted or unresolved claim outside Gaps and Contradictions, or a high-risk claim absent from the verified claims. | The claim id is unknown, refuted, unresolved, or not in verified-claims; move the sentence to Gaps or Contradictions, or remove it. |
|
|
43
44
|
| `incompatible_operands` | blocker | true | A derivation's operands differ in unit, population, period, or accounting basis where the operation requires them to match; derive refuses and writes no row. | The operands differ in unit, population, period, or basis for this operation; fix the rows or declare the operation that fits. |
|
|
44
45
|
| `pointer_label_mismatch` | blocker | true | A placeholder's label differs from the referenced ledger row's label (a typo guard on the id). | The placeholder's label is not the row's label; check the id, then the label. |
|
|
45
46
|
| `quote_anchor_unresolved` | blocker | true | A quote cut's from or to anchor is absent, occurs more than once, or appears in reverse order in the quote. | A from or to anchor is missing or occurs more than once in the quote; pick unique anchor words. |
|
|
46
47
|
| `unit_duplicated` | blocker | true | A unit-bearing placeholder is followed by another copy of its own unit. | The unit after the placeholder repeats the row's unit; use :value or remove the unit. |
|
|
48
|
+
| `conversion_altered_number` | blocker | true | `fact add` located a value (or a number in its sentence) that the source's conversion probe recorded as altered in `sources/S<n>/conversion.json`, such as a footnote digit glued onto it; the converted text cannot back the number, so no row is written. | 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. |
|
|
47
49
|
| `polish_diff_fail` | blocker | true | The polish pass changed protected fact spans, numerals or units, tickers, table rows, or any markup byte (including every attribute, comments, and script/style/template content). | Revert to the pre-polish artifact and apply text-node edits only; markup changes require the full fidelity gates. |
|
|
48
50
|
| `fidelity_interview_incomplete` | blocker | true | A fidelity field in the brief is still pending or missing when a fidelity command runs. | A fidelity field is pending or missing in brief.md; answer the open question or record its default, then rerun. |
|
|
49
51
|
| `derived_not_allowed` | blocker | true | A placeholder resolves to a derived, converted, or assumed row while the brief allows no derived numbers. | The brief allows no derived or assumed numbers; cite a source row directly or change the brief with the requester. |
|
|
50
|
-
| `source_outside_floor` | blocker | true | A ledger row's source lies outside the source floor the brief records (pointed sources only, or the allowed source classes)
|
|
51
|
-
| `
|
|
52
|
+
| `source_outside_floor` | blocker | true | A ledger row's source lies outside the source floor the brief records (pointed sources only, primary only, or the allowed source classes), or the row rests on no source under any floor but `standard`. | The row's source is outside the source floor the brief records; use a source the brief allows or remove the fact. |
|
|
53
|
+
| `brief_changed` | blocker | true | `fact verify` reads an edition's fill map whose recorded brief hash is not the hash of the current locked `## Fidelity` block, or that records none. | 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. |
|
|
54
|
+
| `snapshot_hash_mismatch` | blocker | true | The pinned snapshot body (raw.bin; text.txt for converted-only and legacy sources) differs from its metadata or from a cited row's pinned sha256, or a cited row's sources dir, meta.json, raw.bin, or text.txt cannot be read (the message names the cause). | The source snapshot changed after it was pinned or cannot be read; restore it, or run source refresh to re-anchor its rows. |
|
|
55
|
+
| `snapshot_not_raw` | blocker | true | A measured row rests on a converted-only source (no raw bytes), or `fact add` was run on such a source or on a legacy text.txt snapshot. | Measured rows need the original bytes: snapshot the source with --url, --html, or --raw <bytes> --text <extraction>; converted-only sources support warned quotations only. |
|
|
52
56
|
| `chart_value_untraceable` | blocker | true | A chart data label, axis tick, or chart data file does not match the ledger-backed data the chart declares, or the chart declares no data source. | A chart value, tick, or data file does not match its ledger-backed data source; re-render the chart from the exported data. |
|
|
53
57
|
| `quote_unbound` | blocker | true | A direct quotation in the report has no ledger quote row behind it; a citation marker alone does not bind it. | A direct quotation has no ledger quote row; register it with fact quote and insert it through its placeholder. |
|
|
54
58
|
| `edition_unverified` | blocker | true | A delivered edition has no fact verify record whose artifact hash matches the delivered source. | The delivered file has no matching fact verify record; run fact verify on that edition and record it with --verified-by. |
|
|
55
|
-
| `untraceable_number` | major | false | A number or date in prose or a table cell resolves to no ledger row and is not structural; a citation does not exempt it. | Replace the typed number with a {{F<n>}} placeholder backed by a ledger row, or register it as assumed with a rationale. |
|
|
59
|
+
| `untraceable_number` | major | false | A number or date in prose or a table cell resolves to no ledger row and is not structural; a citation does not exempt it. Under Sources a sentence is traced unless every numeral in it is a citation-field number (see `unsourced_number`). | Replace the typed number with a {{F<n>}} placeholder backed by a ledger row, or register it as assumed with a rationale. |
|
|
56
60
|
| `unsupported_verification` | major | false | A fact bound to a `verified` mark (`data-claim-kind="verified"`, from a `{{V:F<n>:label}}` placeholder) cites a row whose own locator artifact does not sit in a recorded command-output snapshot, or the mark binds no fact of its own. Another command row in the same sentence never counts. Unmarked prose is never raised here. | A sentence marked verified (data-claim-kind="verified") cites a row that is not recorded command output; cite the recorded output row or drop the verified mark. |
|
|
57
61
|
| `claim_kind_mismatch` | major | false | A fact bound to a claim kind cites a row of a kind that claim kind does not accept, a fact sits under marks of two different kinds (nested marks), a mark binds no fact of its own, or a mark names an unknown kind; the kinds are in [fidelity-claim-kinds.md](fidelity-claim-kinds.md). | An element marked with a claim kind (data-claim-kind) cites a row that kind does not accept, or the kind is unknown; cite a row of that kind or fix the mark (references/fidelity-claim-kinds.md). |
|
|
58
62
|
| `conflicting_readings` | major | false | Two active ledger rows with the same value and unit but different periods or qualifiers are cited as one fact. | Two ledger rows with different periods or qualifiers are cited as one fact; split the sentence or retire one row. |
|
|
@@ -67,11 +71,15 @@ Raised only by the fidelity verifier (the fact ledger, fill, verify, meaning, an
|
|
|
67
71
|
| `polish_hedging_decreased` | major | false | The polish pass removed a hedge the source grounds. | The polish pass removed qualifiers; restore them. |
|
|
68
72
|
| `polish_text_churn` | major | false | More than half of the visible prose changed during the polish pass (`POLISH_CHURN_LIMIT` in `scripts/polish-rules.mjs`). | More than half the text changed during polish; the pass composed instead of proofreading. |
|
|
69
73
|
| `snapshot_mismatch` | major | false | An operation that needs one collection window uses operands from unequal windows or observations outside the window. | The operands come from different collection windows; use rows from one window or state the windows separately. |
|
|
74
|
+
| `operand_timestamp_missing` | major | false | A windowed operation cites an operand without an observed_at timestamp. | Record the operand's observed_at timestamp before checking its collection window. |
|
|
75
|
+
| `operand_missing` | major | false | A windowed operation names an operand id that is not in the fact ledger (a dangling reference, not a missing timestamp). | A windowed operation names an operand that is not in the fact ledger; restore the row or re-derive from existing rows. |
|
|
70
76
|
| `join_integrity_fail` | major | false | A table row combines facts from different source observation rows, or a declared observation id contradicts the row's lineage. | A table row combines facts from different source observations; keep each row to one observation or split it. |
|
|
71
77
|
| `quote_stale_version` | major | false | The quoted source revision differs from the revision the report targets for the same scope. | The quoted source revision differs from the revision the report targets; re-snapshot the target revision or date the quote. |
|
|
72
78
|
| `quote_fuzzy_match` | minor | false | An exact quote match failed but a candidate with similarity of at least 0.95 and identical protected tokens exists (OCR noise); diagnostic only. | The source text is OCR-noisy; confirm the snapshot and prefer the raw document. |
|
|
79
|
+
| `relocated` | minor | false | After `source refresh` repinned a source, the row's exact quote and context occur exactly once at a new byte range; old and new offsets are reported. | 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). |
|
|
80
|
+
| `quote_converted_only` | minor | false | A quote row rests on a converted-only source, so it is bound to converted text, not to the fetched bytes; `fact quote` and `fact verify` both report it. | 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. |
|
|
73
81
|
| `name_outside_quote` | minor | false | An uppercase Latin token of 2 to 6 letters in the sentence is absent from the supporting source text and that source's acronym table. | A name in the sentence is not in the cited quote; add the source or remove the name. |
|
|
74
|
-
| `verification_claim_unmarked` | minor | false | A sentence
|
|
82
|
+
| `verification_claim_unmarked` | minor | false | A sentence matches the unmarked cue rule of the `verified` claim kind (a first-person run: we/I (have) ran, run, re-ran, re-run, executed, verified by (not ran out of), or by running after we/our in the sentence; a first-person check: we/I (have) verified, checked, confirmed, measured, tested, double-checked, cross-checked (not checked in/into/out) with a result object in the clause (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, or a digit) and no document named before the clause ends (report, reports, filing, filings, document, documents, paper, papers, article, articles, publication, statement, disclosure, website, page, docs, documentation; a comma, a semicolon, or as, which, who, whom, whose, where 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 \uD655\uC778, \uAC80\uC99D, \uCE21\uC815, \uC810\uAC80 + \uD588, \uD558\uC600, \uD558\uC5EC, \uD574, \uD55C with a result object in the clause (\uACB0\uACFC, \uAC12, \uC218\uCE58, \uAE38\uC774, \uD569\uACC4, \uBE44\uC728, \uC18D\uB3C4, \uC9C0\uD45C, \uB370\uC774\uD130, or a digit) and no document before the clause ends (\uBCF4\uACE0\uC11C, \uBB38\uC11C, \uACF5\uC2DC, \uB17C\uBB38, \uAE30\uC0AC, \uC790\uB8CC; a comma, a semicolon, or \uCC98\uB7FC, \uB4EF\uC774, \uAC19\uC774 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; rendered from CLAIM_KINDS, see fidelity-claim-kinds.md) and cites a fact not marked `verified` (or cites none and its block is unmarked). A warning only; it never blocks. | 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. |
|
|
75
83
|
| `scope_widened_warn` | minor | false | The sentence uses a broader scope term than the quote's narrow term, and no supporting fact carries the broad scope. | The sentence uses a broader scope word than the quote; confirm the scope or narrow it. |
|
|
76
84
|
| `particle_unverified` | minor | false | A particle after a filled value could not be checked against the value's final reading. | The particle after this value could not be checked; read it aloud and fix it by hand if wrong. |
|
|
77
85
|
| `fallback_without_entity` | minor | false | A quote that replaced a twice-failed sentence has no entity for its attribution line. | The replacement quote has no entity for attribution; set one on the row. |
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
## Phase 0 — Decompose and open the journal
|
|
2
|
+
|
|
3
|
+
Before spawning anything, decompose the query. Start from "what must be true if the user's intent/spec is true?", not "what looks broken?" Seed `intent-diff.md` with those expected truths before treating code, current docs, or web results as the source of truth:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
<analysis>
|
|
7
|
+
Core question: <the actual information need>
|
|
8
|
+
Axes (3+ orthogonal): <axis — what to search, where, why> ...
|
|
9
|
+
Codebase relevant: <yes/no> · External: <yes/no> · Collection: <search-only | browser> · Verification likely: <yes/no>
|
|
10
|
+
Scale: <axis count, source territories, target document length> · Precision demand: <what a wrong claim costs here> → lifecycle: <single team | research team then refinement team>
|
|
11
|
+
</analysis>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`Collection` is `search-only` only when a result snippet settles every axis (a date, a version, a spec value); anything that needs reading a source is `browser`.
|
|
15
|
+
|
|
16
|
+
Then create the session directory:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
mkdir -p .omo/ulw-research/$(date +%Y%m%d-%H%M%S)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This is `$SESSION_DIR`. The orchestrator owns the journal: you write every file in it; workers never do (a mass-research dag node writes only its own `waves/<run-key>/<node-id>.md` handoff file, which carries its EXPAND tail and claim candidates; you journal from it). Maintain:
|
|
23
|
+
|
|
24
|
+
- `brief.md` — the analysis block, the axis list, the expected truths, and the `## Deliverable` record from the interview below (lane, state, formats, each field with `answered_by`).
|
|
25
|
+
- `sources-ledger.md` — one line per source the moment it is read: `[S<n>] <url> — <what it is>`. The closing briefing counts sources and domains from this file.
|
|
26
|
+
- `sources/` and `fact-ledger.json` — one directory per source snapshot and the ledger built from them. The snapshot and locator contract (raw bytes, converted-only sources, byte locators, `source refresh`) is defined once, in [fact-ledger.md](fact-ledger.md#snapshot-and-locator-contract); every number and quotation reaches the report through a ledger placeholder.
|
|
27
|
+
- `wave-<N>-<kind>-<axis>.md` — your digest of each worker return: key findings, sources with URLs, and the worker's EXPAND markers verbatim.
|
|
28
|
+
- `expansion-log.md` — per wave: workers spawned, markers gained, leads opened and closed.
|
|
29
|
+
- `excursion-log.md` — one ENTER row and one EXIT row per excursion: `excursion_id`, parent claim or axis, ENTER trigger, depth, workers spent, the EXIT rule that closed it, what it changed in the top-level answer (`none` is a valid, required answer), and the ulw-loop steer/evidence id it was mirrored into.
|
|
30
|
+
- `intent-diff.md` — orchestrator-owned expected-truth ledger comparing intent/spec/history to observed reality.
|
|
31
|
+
- `claim-graph.md` — orchestrator-owned claim graph linking every final assertion to observations, counterevidence, dependencies, and verdict.
|
|
32
|
+
- `observation-manifest.md` — orchestrator-owned observation manifest with `observed_at`, temporal validity, artifact paths, and contamination notes.
|
|
33
|
+
- `verification-economics.md` — proof-cost ledger mapping claim risk to verification path, deferral decisions, and residual risk.
|
|
34
|
+
- `cause-disappearance.md` — cause ledger tracking expected truth, previous observation, `last_seen`, disconfirming observation, and whether the violation is no longer observed.
|
|
35
|
+
- `verify-<slug>.md`, `SYNTHESIS.md`, `REPORT.*` from later phases.
|
|
36
|
+
|
|
37
|
+
Append each digest the moment its worker returns, not in a batch at the end — the journal is your recovery point after context loss and the user's audit trail.
|
|
38
|
+
|
|
39
|
+
### Run it as a loop, and journal in real time
|
|
40
|
+
|
|
41
|
+
ulw-loop is ON by default for this mode: when the `ulw-loop` skill is available, register the research axes as loop goals so the run has durable state and survives a compaction. The run's start clock is `outcome.json` `startedAt`, which `outcome init` records once: from `--started-at <ISO>` when you pass it, else from this directory's timestamp name — the closing briefing is computed from it, so create the directory once and never rename it. From that point every finding, source, quote, number, and lead is written into `$SESSION_DIR` **the instant it lands** — never held in the conversation for an end-of-run dump. After any context loss, re-read the brief and the journal before doing anything else, then resume from the open wave.
|
|
42
|
+
|
|
43
|
+
### Deliverable lane, format, and the empty-info interview
|
|
44
|
+
|
|
45
|
+
Never block collection on the shape of the deliverable, and never guess it either. Read [references/deliverable-phase.md](deliverable-phase.md) sections 1-6 before writing the brief, then:
|
|
46
|
+
|
|
47
|
+
1. **Derive first.** Name the lane (`template-strict`, `template-vibe`, `no-format`, `edit-existing`) and the promised formats from the request and its destination (the reference's section 3). When the request refers to an existing deliverable, decide its state with `node "$SKILL_DIR/scripts/report-tools.mjs" outcome state --deliverable <path> --session-dir "$SESSION_DIR"`: `partial` resumes the skeleton on disk, `complete` means edit-existing and never a regenerated report. `$SKILL_DIR` is this skill's own directory, the folder containing this SKILL.md.
|
|
48
|
+
2. **Read the requester's format memory** with the memory tool when the harness exposes one: the pointer `system/human/report-style.md`, then `reference/human-report-style.md`; take the choice recorded for the most similar context (same destination kind and audience) as the first option.
|
|
49
|
+
3. **Ask only what is still missing**: at most the reference's three questions (destination and format, audience and length, template lineage) in one call to the harness question tool (`ask_user_question` or `request_user_input`), non-blocking where the harness supports it, each with its default first, a free-text "describe the format" path, and "don't care, you decide". Collection starts without waiting; a late answer is folded in until the assembly worker starts, and after that it becomes a re-render request.
|
|
50
|
+
4. **Settle source fidelity in the same step.** Seven fields under `## Fidelity` in `brief.md` say what the report must stay faithful to; the reference's section 4 lists each field's values and default. Infer every field before asking anything; an explicit word in the request decides a field (`answered_by: request`), the destination, the sources, and the Phase 0 axes supply the rest (`answered_by: default`):
|
|
51
|
+
- `as of`: a version, release, tag, commit, date, quarter, "as of", "current", or "latest" in the request decides it; a pointed-at repository anchors on its HEAD or tag at run start, pointed-at documents on their own revisions, and a comparison of two anchors records `multiple: <a>, <b>; rows tagged`. Default `latest at run start, <run date>`, the date of the `$SESSION_DIR` timestamp. Ask when the topic is version-bound or time-sensitive (software, APIs, standards, prices, rates, rankings, laws, programs, schedules) and nothing names an anchor; a stable topic takes the default silently.
|
|
52
|
+
- `meaning check`: the QA tier decides (full: `on`, light: `off`); a chat answer on a legal, medical, financial, procurement, or public-facing question with no speed word is `on`. Ask when two explicit signals disagree: a document deliverable under a literal "quick" or "fast", or a light-tier answer that carries both a speed word and a precision demand; `on` goes first.
|
|
53
|
+
- `source floor`: "official docs only", "peer-reviewed only", "SEC filings" give `primary only` or `classes: <host suffixes>`; "from these only" gives `pointed only: <source ids, URLs, or paths>`; pointed-at sources with no restricting word are seeds, not a floor. Default `standard`. Ask when a restricting phrase sits beside an open-ended question whose answer lives outside that floor. Declare each source's provenance when you snapshot it (`source snapshot --provenance primary|secondary`, by the Phase 3b primary-source rule); `primary only` refuses every source not declared `primary`.
|
|
54
|
+
- `derived numbers`: "compare", "growth", "share", "estimate" give `allowed`; "only the sources' own numbers", "no estimates" give `none`. Default `allowed`. Ask when both kinds of phrase share one request. Record only `allowed` or `none` (any other value stops `fact fill` and `fact verify` with a usage error); a partial or free-text answer records `none`.
|
|
55
|
+
- `languages` (never asked): the report in the user's language or the one they named; sources `en`, plus the user's language for a local topic, plus the pointed-at documents' languages; quotes `original` when every source language equals the report language, else `original with translation beside`.
|
|
56
|
+
- `identifier classes` (never asked): from the Phase 0 axes' domain (software: version strings, package names, commit ids; finance: tickers, filing ids, fiscal periods; law: statute, article, and case numbers; science: gene names, DOIs, trial ids), else `none`. It is recorded only; no gate enforces it yet.
|
|
57
|
+
- `fallback` (never asked): `block-quote`, or `omit` on "drop anything you cannot verify"; no other value is accepted.
|
|
58
|
+
|
|
59
|
+
Ask nothing when the request, the destination, and the sources decide every field. Otherwise ask only the fields whose trigger fired, in the same question-tool call as the format questions (`ask_user_question` or `request_user_input`), non-blocking where the harness supports it, each with its default first, a free-text path, and "don't care, you decide" (it resolves to the first option, recorded `answered_by: user`). At most four questions ride in that call: `pending` fidelity fields first, then format Q1, Q2, Q3, then `as of`, `meaning check`, `source floor`, `derived numbers`; a question that loses its slot runs on its default and is named, with that default, in the reply that opens collection. When each reading of a field would make part of the request undeliverable, record it `pending` with no default. Collection starts regardless: `source snapshot`, `fact add`, `fact quote`, `fact derive`, `fact retract`, and `fact export` keep working while answers are pending; only the six reader-facing commands (`fact fill`, `fact verify`, `fact pairs`, `fact meaning-check`, `fact polish-apply`, `fact polish-diff`) and the assembly lane wait for the lock, and those commands exit 1 with `fidelity_interview_incomplete` while a field is `pending` or missing. When the assembly lane is about to start, a field still awaiting its answer keeps its default; a `pending` field is asked once more, blocking this time.
|
|
60
|
+
5. **Record it.** Write `## Deliverable` into `brief.md` (lane, state, formats, destination, audience, template, format description, each with `answered_by: user|default|request`) plus `## Fidelity` (the block below), and open the manifest in the same step: `node "$SKILL_DIR/scripts/report-tools.mjs" outcome init --promised <formats> --lane <lane> --session-dir "$SESSION_DIR"`. When the ask is to recreate, reproduce, or rebuild something visual, add `Reference compare: required` with the source (URL or file) and the moments to compare; the comparison runs on every round of the build, not only at the end.
|
|
61
|
+
|
|
62
|
+
#### The fidelity questions
|
|
63
|
+
|
|
64
|
+
Ask them in the user's language, translating these English texts faithfully and keeping the option order; `<run date>` is the `$SESSION_DIR` date.
|
|
65
|
+
|
|
66
|
+
- **`as of`**, header `As of`: "Which version or date must the facts hold for? Sources are snapshotted and quoted against that anchor."
|
|
67
|
+
1. `Latest as of today, <run date>` - The state published at the run's start; anything older is flagged as stale.
|
|
68
|
+
2. `Other: a named version, release, or date` - Type it (v3.2, 2026-Q3, a commit or tag). Every quote and number is checked against sources valid at that anchor.
|
|
69
|
+
3. `Don't care, you decide` - Resolves to option 1.
|
|
70
|
+
- **`meaning check`**, header `Drift check`: "Numbers and quotes are always script-checked against source snapshots. Should every explanatory sentence also be read against its source quote by a separate reader? Slower and more tokens; it catches widened scope and dropped hedges."
|
|
71
|
+
1. `On` - Every sentence is paired with its source and read; confirmed drift is rewritten from the quote or listed in the briefing.
|
|
72
|
+
2. `Off (faster)` - Script checks only: numbers, units, quotes, qualifiers, bindings. A paraphrase that shifts meaning is not read.
|
|
73
|
+
3. `Other: where to focus` - Type it ("the financial sections", "anything about the competitor"); those pairs go to the strongest reader.
|
|
74
|
+
4. `Don't care, you decide` - Resolves to option 1.
|
|
75
|
+
- **`source floor`**, header `Sources`: "Which sources may back a statement of fact?"
|
|
76
|
+
1. `Standard: primary source required for high-risk claims` - Numeric, legal, financial, dated, and causal claims need a primary source plus two independent domains; other claims may cite attributed secondary sources.
|
|
77
|
+
2. `Primary only` - Every fact traces to a first-party source (standard, filing, dataset, official doc); commentary appears only as attributed opinion.
|
|
78
|
+
3. `Only the sources I pointed at` - Ledger rows come from the named files and URLs only; anything else is context, not evidence.
|
|
79
|
+
4. `Other: name the source classes` - Type it ("peer-reviewed only", "no vendor blogs").
|
|
80
|
+
5. `Don't care, you decide` - Resolves to option 1.
|
|
81
|
+
- **`derived numbers`**, header `Derived`: "May the report state numbers no source states (sums, growth rates, shares, unit conversions, estimates)?"
|
|
82
|
+
1. `Yes, computed by script and labeled DERIVED` - Each one names its operation and input rows; inputs are checked for unit, period, and population compatibility; an estimate carries its assumptions.
|
|
83
|
+
2. `No, sourced numbers only` - Every number is a MEASURED ledger value; comparisons are stated in words or shown side by side.
|
|
84
|
+
3. `Other: describe` - Type it ("growth rates yes, estimates no"). A partial allowance is recorded as `none`, and the reply that opens collection says so.
|
|
85
|
+
4. `Don't care, you decide` - Resolves to option 1.
|
|
86
|
+
|
|
87
|
+
#### The `## Fidelity` block
|
|
88
|
+
|
|
89
|
+
Write it in the same step as `## Deliverable`, provisional defaults included, one line per field with its `answered_by`, plus an `asked:` line naming the fidelity questions sent:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
## Fidelity
|
|
93
|
+
as of: latest at run start, 2026-10-23 (answered_by: default)
|
|
94
|
+
meaning check: on (answered_by: default)
|
|
95
|
+
source floor: standard (answered_by: default)
|
|
96
|
+
derived numbers: pending (answered_by: pending)
|
|
97
|
+
languages: report en; sources en; quotes original (answered_by: default)
|
|
98
|
+
identifier classes: version strings, package names, commit ids (answered_by: default)
|
|
99
|
+
fallback: block-quote (answered_by: default)
|
|
100
|
+
asked: derived numbers
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Values carry no parentheses; `pending` goes only with `answered_by: pending`. When an answer lands, rewrite that one line with `answered_by: user` and leave `asked:` as history; a late answer after `fact fill` is a re-render: fill again, then verify.
|
|
104
|
+
|
|
105
|
+
**Re-entry.** An `edit-existing` session, or any session created before this block existed, has no `## Fidelity`. Before any `fact` command, run the inference step above and write the block with `answered_by: default` on every field. `claims index` on a free-form `claim-graph.md` (no claim table) returns `{claims: [], errors: [...]}`, exits 2, and writes no `claims.json`; run `fact verify` without it, and the gate reports each unbound sentence as `unbound_sentence` (major) instead of blocking.
|
|
106
|
+
|
|
107
|
+
**Calibration.** `fact meaning-check` appends one line per flagged pair to `--calibration` (default `$SESSION_DIR/fidelity-calibration.jsonl`). After each run, also append that run's new lines to the workspace-level `.omo/ulw-research/fidelity-calibration.jsonl`; promotion of `meaning_drift_confirmed` is decided from that log.
|
|
108
|
+
|
|
109
|
+
Phase 5 opens by turning the recorded fields into `design-spec.md`.
|
|
110
|
+
|
|
111
|
+
## Phase 1 — Saturation wave
|
|
112
|
+
|
|
113
|
+
**When the user asked for MASS research, the wave is sized by the topic's angles, not by the roster ceiling.** "mass ulw research", "mulw research", "ulw mass research" — in any language — order over-collection that a team of 8 cannot produce. Where the harness has a dependency-graph surface (the `mass-ulw` skill and its `references/planning.md`), run collection through it instead: 60+ angles covering every angle the topic has, routed across the whole difficulty ladder — mechanical sweeps and per-item harvest batches on the cheapest tier, judgment-shaped angles a step up, cross-territory angles a step above that, and the deepest tier reserved for genuinely hairy contradictions. Define each angle as a harvest -> expand -> verify chain before the run starts, each stage reading the previous stage's handoff file; open leads re-enter as new chains in each cluster of angles the moment that cluster settles, and the synthesis reduces through per-cluster architect-tier slice reducers into ONE architect-tier reducer (the strongest reasoning tier substitutes wherever no architect tier exists). Absent that surface, run the same per-angle chains with background workers, pasting each worker's reply into its angle's next-stage prompt the moment it reports. Everything else in this skill still binds: the deliverable interview, the journal, the claim graph, the convergence rules, and the delivery gates.
|
|
114
|
+
|
|
115
|
+
Otherwise launch the entire first wave in one turn — every axis at once, as team members if you formed a team, else as background workers. Sequential launches and "start with one and see" defeat the mode.
|
|
116
|
+
|
|
117
|
+
Scaling floor — more angles always justify more workers:
|
|
118
|
+
|
|
119
|
+
| Query scope | explore | web | repo-dive | floor |
|
|
120
|
+
|---|---|---|---|---|
|
|
121
|
+
| Single topic, codebase only | 3 | 0 | 0 | 3 |
|
|
122
|
+
| Single topic, web only | 0 | 5 | 1 | 6 |
|
|
123
|
+
| Single topic, both | 2 | 4 | 1 | 7 |
|
|
124
|
+
| Multi-faceted | 4 | 8 | 2 | 14 |
|
|
125
|
+
| Full due diligence | 4 | 9 | 2 | 15 |
|
|
126
|
+
|
|
127
|
+
**Disambiguate before you expand.** When the topic names something that could resolve several ways — a product, a person, a codename, a version — the first wave settles WHICH entity before any worker researches its history, benchmarks, or controversies: canonical name, first-party URL or account, whether it exists in the claimed category, and a confidence line. An unresolved entity never becomes a premise in a later wave's spawn message; that is exactly how a run starts inventing facts about something that does not exist.
|
|
128
|
+
|
|
129
|
+
Role protocols — embed the relevant one in each spawn message; every worker gets a unique angle:
|
|
130
|
+
|
|
131
|
+
- **Codebase (explore), 2-4 workers.** Grep with 3+ keyword variations; structural/AST search; LSP definitions and references; file-name globs; `git log --all -S '<keyword>'` and `--grep` for history including deleted code. Cross-validate hits across tools. Report absolute file paths, patterns with `file:line`, and how findings connect.
|
|
132
|
+
- **Web, 3-9 workers, every one loaded with the `browser` skill.** Search with 10+ websearch queries per worker, each with a different operator or angle (see Search craft); a result is a candidate, not a source. Read every candidate in the user's browser through the `browser` skill's attached engine: one named session per worker, one tab per source, several tabs open side by side while sources are compared — `session.tabCreate` / `tabSelect` / `tabClose` where the harness has a JS eval kernel, `bsk tab create --url <url>` / `tab select <id>` / `tab close <id>` / `tab list` on the CLI — the page scrolled to its end, a full-page screenshot of each top source saved as provenance, the tab closed once reported. A browser on another machine is reached through the `browser` skill's remote reference or a user-level skill that bridges to it, never replaced by a local headless one. `webfetch` is for raw files only: PDF, JSON, feeds, sitemaps. A host the browser cannot open (WAF, bot score, 403) goes to `ultimate-browsing`, whose provenance travels with the claim: a `snapshot` result cites its `snapshot_timestamp` and is never stated as the live page; a `proxy` result is `untrusted` until a second independent route agrees. Context7 with 3+ queries per known library; grep.app and `gh search code|repos|issues` for real-world usage; official docs via sitemap discovery (`<base>/sitemap.xml`), then targeted pages. A worker whose sources are all fetched text has searched, not read.
|
|
133
|
+
- **Repo deep-dive (librarian), 0-2 workers.** Shallow-clone the most relevant repos to `${TMPDIR:-/tmp}`, pin the HEAD SHA, read core modules, follow call chains, return SHA-pinned permalinks.
|
|
134
|
+
|
|
135
|
+
Example spawn (codebase axis; web and repo-dive follow the same contract with their own protocol):
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
task(subagent_type="explore", run_in_background=true, prompt="TASK: act as a codebase researcher. AXIS: <specific angle>.
|
|
139
|
+
This is an explicit exhaustive-research assignment. Your default retrieval budget and stop-when-answered rules do not apply — run the full protocol below and report every lead.
|
|
140
|
+
SCOPE: find everything in this codebase related to <angle>: <what complete looks like>.
|
|
141
|
+
PROTOCOL: grep 3+ keyword variations; structural search; LSP references; globs; git history (-S and --grep). Cross-validate across tools. Report absolute paths and file:line patterns.
|
|
142
|
+
End your reply with the ## EXPAND tail: '- LEAD: <discovery> — WHY: <why> — ANGLE: <search>' per lead, or 'none — <reason>'.")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Phase 2 — Expand until convergence
|
|
146
|
+
|
|
147
|
+
This loop is what makes the mode research rather than search. Collect returns as they land — and in team mode, act on each lead the moment a member raises it, never waiting for the full wave or a member's final reply:
|
|
148
|
+
|
|
149
|
+
1. Journal the return the moment it lands, never at the end of the wave: digest plus verbatim EXPAND markers into `wave-<N>-<kind>-<axis>.md`, appending each new source, quote, and number to the observation manifest in the same beat — after a compaction the journal, not your memory, is the state. Snapshot each source the moment it is read (`node "$SKILL_DIR/scripts/report-tools.mjs" source snapshot --id S<n> --url <url> --session-dir "$SESSION_DIR"`; a page read in the browser is saved and imported with `--html <file>`, recorded as lower-trust `model` extraction), then register every number and quote you will use from that snapshot: `fact add --source S<n> --find "<anchor text>" --label <label>` (or `--table <id> --row <label> --col <label>`, or `--page <n> --line <n>`) and `fact quote --source S<n> --match "<words>" --label <label>`. Read the printed row and its 60 characters of source context before using it; a wrong row is retracted (`fact retract F<n> --reason <why>`), never edited. The observation's quote or line anchor in the manifest is that fact id.
|
|
150
|
+
2. Deduplicate new markers against `expansion-log.md` — every lead ever seen, not just confirmed ones, or rejected leads resurface each wave.
|
|
151
|
+
3. Spawn an expansion worker immediately for each new unchecked lead:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
task(category="deep-low", load_skills=["browser"], run_in_background=true, prompt="TASK: expansion wave <N> — investigate: <lead>.
|
|
155
|
+
PARENT: <which return surfaced it>. This is an explicit exhaustive-research assignment; budgets do not apply.
|
|
156
|
+
<role protocol for the lead's territory — web protocol for external leads, explore protocol for codebase leads>
|
|
157
|
+
End your reply with the ## EXPAND tail.")
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Excursions — dive deep on a new find, then surface back out
|
|
161
|
+
|
|
162
|
+
The Phase 0 core question is the fixed goal of the run and never drifts. An excursion is a BOUNDED detour off the wave plan to chase something a return surfaced — you go deep, settle it, and come back up to the question you were hired to answer.
|
|
163
|
+
|
|
164
|
+
**ENTER (dive) only on a trigger.** One of these must hold, and you name which one:
|
|
165
|
+
|
|
166
|
+
1. The find contradicts a claim already locked in `claim-graph.md`.
|
|
167
|
+
2. It would change the final answer or a recommendation if it turned out to be true.
|
|
168
|
+
3. It exposes a source territory no axis owns, so nobody else will ever reach it.
|
|
169
|
+
4. The user's steering points at it — their words are the trigger, quoted verbatim.
|
|
170
|
+
|
|
171
|
+
Interest alone is not a trigger. Anything without one stays a queued lead in `expansion-log.md`, and the wave plan continues.
|
|
172
|
+
|
|
173
|
+
**Budget the dive before you take it.** State the worker count and the probe count for this level in the ENTER row. An excursion may spawn at most ONE nested sub-excursion; a third level means the thing has become its own research question — surface immediately and either promote it to a real axis with its own worker or record it as an out-of-scope gap in `SYNTHESIS.md`. When the `ulw-loop` skill is driving the run, a promotion is `omo-agent-toolkit ulw-loop steer --kind add_subgoal --title "<axis>" --objective "<what it must answer>" --evidence "<what surfaced it>" --rationale "<why the plan changes>"`.
|
|
174
|
+
|
|
175
|
+
**EXIT (surface) the moment any of these holds** — you do not need all of them:
|
|
176
|
+
|
|
177
|
+
- The ENTER trigger is resolved: the claim is confirmed, refuted, or its dependency is closed.
|
|
178
|
+
- Two consecutive probes changed nothing in the parent answer.
|
|
179
|
+
- The finding stops moving any claim's status — diminishing return is an exit, not a reason to push harder.
|
|
180
|
+
- The level's stated budget is spent.
|
|
181
|
+
|
|
182
|
+
**Fold back on the way out.** Every EXIT writes one line saying what the excursion changed in the top-level answer, and `none — <reason>` is a legitimate, required outcome; an excursion whose result is silently dropped is a lost run. Update the parent claim node or axis digest with the result, then mirror the whole excursion into the loop ledger — `omo-agent-toolkit ulw-loop steer --kind annotate_ledger --evidence "<what the excursion observed>" --rationale "<what it changed, or none>"`, and `omo-agent-toolkit ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass|fail|blocked --evidence "<artifact>"` when it settled a criterion. After a compaction, `omo-agent-toolkit ulw-loop status --json` plus `excursion-log.md` tell you which excursions are still open.
|
|
183
|
+
|
|
184
|
+
**Anti-drift.** After every EXIT, re-read the core question in the journal and confirm the run still answers it. Three consecutive excursions that changed nothing end excursions for the run: converge on what you have.
|
|
185
|
+
|
|
186
|
+
4. Record the wave in `expansion-log.md`: spawned, markers gained, leads opened/closed.
|
|
187
|
+
5. **Relay the user's steering to everyone.** When the user changes scope, cadence, target sources, language, or format mid-run, broadcast it to every live worker and member immediately and record the exact wording in `expansion-log.md`. Steering only you saw silently splits the swarm's assignment from the user's actual ask.
|
|
188
|
+
|
|
189
|
+
**Convergence — the only stop rules while this mode is active.** Run at least 2 expansion waves on any multi-faceted query before claiming convergence; then stop only when one holds:
|
|
190
|
+
|
|
191
|
+
- Zero unchecked leads remain — each investigated or closed as duplicate/dead end.
|
|
192
|
+
- 3 consecutive waves produced no new actionable leads.
|
|
193
|
+
- Expansion depth reached 5 waves — pause, show the open leads, and ask the user whether to extend.
|
|
194
|
+
|
|
195
|
+
**Never end the run on a worker's completion.** Workers finishing is not the deliverable; your synthesis is. Reserve the last fifth of the run's context and time for Phases 4-5 and stop opening waves the moment that reserve is threatened. A converged answer with two open leads beats nine finished workers and no report.
|