feat: facts audit/extract/crm shebang wrappers (D14) (#19)
Python stays the implementation. Commands are bin/facts/{audit,extract,crm}.go
like postgres/query.go.
This commit is contained in:
@@ -77,8 +77,8 @@ bin/brain/index.go --rebuild # rebuil
|
|||||||
## Tools
|
## Tools
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bin/facts/audit ["self"|"facts"|"info"|"stale"] # 2-source + staleness gate
|
bin/facts/audit.go ["self"|"facts"|"info"|"stale"] # 2-source + staleness gate
|
||||||
bin/facts/crm [--dry-run] # proof person↔company/company↔project (ooCRM × corpus SoT)
|
bin/facts/crm.go [--dry-run] # proof person↔company/company↔project (ooCRM × corpus SoT)
|
||||||
bin/kb/search "query" [--repo X] # deprecated wrapper → bin/brain/search.go
|
bin/kb/search "query" [--repo X] # deprecated wrapper → bin/brain/search.go
|
||||||
bin/brain/search.go "query" [--root facts|info] # deduction search → YAML
|
bin/brain/search.go "query" [--root facts|info] # deduction search → YAML
|
||||||
bin/brain/search.go "query" --no-web # local graph only
|
bin/brain/search.go "query" --no-web # local graph only
|
||||||
|
|||||||
@@ -52,8 +52,7 @@ detective method: **a fact needs ≥2 independent sources or it is
|
|||||||
docs/ published docs (this conversation → docs/ as md)
|
docs/ published docs (this conversation → docs/ as md)
|
||||||
skills/ in-project skills (web-search, db-yaml, brain, diataxis-docs)
|
skills/ in-project skills (web-search, db-yaml, brain, diataxis-docs)
|
||||||
bin/
|
bin/
|
||||||
facts/extract auto-pair 2 sources → lexicon yaml + graph
|
facts/extract.go audit.go crm.go # D14 shebang; Python implementation
|
||||||
facts/audit ["self"|"facts"|"info"|"stale"] 2-source + staleness gate
|
|
||||||
kb/index Python write path (called by bin/brain/index.go)
|
kb/index Python write path (called by bin/brain/index.go)
|
||||||
brain/index.go rebuild FTS + HNSW (incl. --with-mail)
|
brain/index.go rebuild FTS + HNSW (incl. --with-mail)
|
||||||
brain/get.go stats.go eval.go # Go read (cgo); Python bin/kb/* CI fallback
|
brain/get.go stats.go eval.go # Go read (cgo); Python bin/kb/* CI fallback
|
||||||
@@ -133,7 +132,7 @@ Common props on every node/edge: `root`, `confidence`, `evidence[]`, `how`,
|
|||||||
1. go vet + go test ./... (root module; packages without ladybug cgo)
|
1. go vet + go test ./... (root module; packages without ladybug cgo)
|
||||||
2. `go test ./internal/brain/rank` (cgo-free ranking + flag parser)
|
2. `go test ./internal/brain/rank` (cgo-free ranking + flag parser)
|
||||||
3. python -m unittest discover -s bin/tools (includes published-docs SoT)
|
3. python -m unittest discover -s bin/tools (includes published-docs SoT)
|
||||||
4. bin/facts/audit self (lexicon internal consistency)
|
4. `bin/facts/audit self` (lexicon internal consistency; `bin/facts/audit.go` is the D14 wrapper)
|
||||||
5. `bin/kb/eval` (recall@5 ≥ 0.95). Local SoT is `bin/brain/eval.go`; CI uses
|
5. `bin/kb/eval` (recall@5 ≥ 0.95). Local SoT is `bin/brain/eval.go`; CI uses
|
||||||
the Python twin until the runner has ladybug cgo. Questions live in
|
the Python twin until the runner has ladybug cgo. Questions live in
|
||||||
`internal/brain/rank`.
|
`internal/brain/rank`.
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ graph TB
|
|||||||
end
|
end
|
||||||
|
|
||||||
subgraph dph["2dph tools"]
|
subgraph dph["2dph tools"]
|
||||||
EX["bin/facts/extract<br/>2-source pairing"]
|
EX["bin/facts/extract.go<br/>2-source pairing"]
|
||||||
AU["bin/facts/audit<br/>confidence + staleness"]
|
AU["bin/facts/audit.go<br/>confidence + staleness"]
|
||||||
IDX["bin/brain/index.go<br/>chunk + embed"]
|
IDX["bin/brain/index.go<br/>chunk + embed"]
|
||||||
MD["bin/markdown/import.go<br/>mistune leaves"]
|
MD["bin/markdown/import.go<br/>mistune leaves"]
|
||||||
SR["bin/brain/search.go<br/>deduction"]
|
SR["bin/brain/search.go<br/>deduction"]
|
||||||
@@ -148,7 +148,7 @@ machines. Tests gate every commit. HTTP: `bin/brain/serve.go` calls
|
|||||||
```bash
|
```bash
|
||||||
uv venv .venv # Python 3.12, uv-managed
|
uv venv .venv # Python 3.12, uv-managed
|
||||||
uv pip install -r requirements.lock.txt # pinned toolchain
|
uv pip install -r requirements.lock.txt # pinned toolchain
|
||||||
bin/facts/audit self # lexicon consistency gate
|
bin/facts/audit.go self # lexicon consistency gate
|
||||||
go test ./... && python -m unittest discover -s bin/tools -t .
|
go test ./... && python -m unittest discover -s bin/tools -t .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Executable
+21
@@ -0,0 +1,21 @@
|
|||||||
|
//usr/bin/env go run -tags=facts_audit "$0" "$@"; exit
|
||||||
|
//go:build facts_audit
|
||||||
|
//
|
||||||
|
// bin/facts/audit.go - 2-source + lexicon checks.
|
||||||
|
//
|
||||||
|
// ./bin/facts/audit.go self
|
||||||
|
// ./bin/facts/audit.go db
|
||||||
|
//
|
||||||
|
// Python bin/facts/audit is the implementation (CI runs it directly).
|
||||||
|
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/eSlider/2dph/internal/cmdbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
os.Exit(cmdbin.ExecFile("bin/facts/audit", os.Args[1:]))
|
||||||
|
}
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
//usr/bin/env go run -tags=facts_crm "$0" "$@"; exit
|
||||||
|
//go:build facts_crm
|
||||||
|
//
|
||||||
|
// bin/facts/crm.go - prove person↔company / company↔project (ooCRM × corpus).
|
||||||
|
//
|
||||||
|
// ./bin/facts/crm.go [--dry-run] [--mismatches]
|
||||||
|
//
|
||||||
|
// Python bin/facts/crm is the implementation. Graph write stays Python.
|
||||||
|
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/eSlider/2dph/internal/cmdbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
os.Exit(cmdbin.ExecFile("bin/facts/crm", os.Args[1:]))
|
||||||
|
}
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
//usr/bin/env go run -tags=facts_extract "$0" "$@"; exit
|
||||||
|
//go:build facts_extract
|
||||||
|
//
|
||||||
|
// bin/facts/extract.go - acquire confirmed facts (2-source each).
|
||||||
|
//
|
||||||
|
// ./bin/facts/extract.go [--json] [--dry-run]
|
||||||
|
//
|
||||||
|
// Python bin/facts/extract is the implementation. Graph write stays Python.
|
||||||
|
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/eSlider/2dph/internal/cmdbin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
os.Exit(cmdbin.ExecFile("bin/facts/extract", os.Args[1:]))
|
||||||
|
}
|
||||||
@@ -108,6 +108,13 @@ class BinLayoutTest(unittest.TestCase):
|
|||||||
self.assertIn(frag, py)
|
self.assertIn(frag, py)
|
||||||
self.assertIn("0.95", rank)
|
self.assertIn("0.95", rank)
|
||||||
|
|
||||||
|
def test_facts_methods_are_shebangs(self) -> None:
|
||||||
|
for method in ("audit.go", "extract.go", "crm.go"):
|
||||||
|
self._assert_shebang(f"bin/facts/{method}")
|
||||||
|
text = (ROOT / "bin" / "facts" / method).read_text()
|
||||||
|
self.assertIn("cmdbin.ExecFile", text)
|
||||||
|
self.assertIn(f"bin/facts/{method.removesuffix('.go')}", text)
|
||||||
|
|
||||||
def test_mail_import_is_shebang_not_brain_write(self) -> None:
|
def test_mail_import_is_shebang_not_brain_write(self) -> None:
|
||||||
self._assert_shebang("bin/mail/import.go")
|
self._assert_shebang("bin/mail/import.go")
|
||||||
index_mail = (ROOT / "bin" / "mail" / "index_mail").read_text()
|
index_mail = (ROOT / "bin" / "mail" / "index_mail").read_text()
|
||||||
|
|||||||
Reference in New Issue
Block a user