Arising from qst-0005 — Will kazi accept the two upstream additions dira's seams still depend on?
Pin kazi's emitted portfolio/status contract now, instead of waiting on qst-0005
qst-0005 asks kazi's maintainer to register `portfolio` in `Kazi.CLI.Schema` and names its own fallback if that is declined: *"(1) declined → dira pins the shape and tests against a recorded fixture, accepting breakage risk on kazi upgrades."* The founder's call on 2026-08-14 is to invoke that fallback now, without waiting for a decline — qst-0005 stays `open` and genuinely unanswered upstream (filing the two GitHub issues is E9's job, not this lane's), but dira's own posture toward it changes: E4 no longer blocks on the answer.
The fact this leans on, verified against source rather than assumed: `schema_version` is lockstep across kazi's entire `--json` surface — `@run_schema_version 2` (`lib/kazi/cli.ex:95`), stamped by both `portfolio_json/1` (`cli.ex:4249`) and `run_status_json/6`, the `status <ref> --json` encoder, and neither is a private constant scoped to one command. Pinning `2` therefore pins both surfaces this lane's client wraps, not just the unregistered one — the version gate `internal/kazi` implements degrades to a `ContractDrift` flag, never an error, exactly because a bump on either surface is the same signal either way.
`internal/kazi` (E4-L1) is the concrete result: a typed client that decodes `kazi portfolio --json` and `kazi status <ref> --json` against a committed fixture corpus, never against a live binary in any test, and degrades gracefully — a typed `Unavailable`, never a bare error or a silent empty result — whenever kazi is absent, exits non-zero, prints something that does not parse, or answers with the wrong `kind`.
Alternatives on record — 3
✗Keep E4 blocked on qst-0005's answer until kazi's maintainer registers `portfolio` in Kazi.CLI.Schemarefused qst-0005 already names this exact fallback as its own answer if declined, and there is no reason to wait for a decline that may never come in order to invoke an outcome the question itself already treats as acceptable.
The risk waiting would avoid — an unpinned shape drifting under dira — is exactly what pinning against a recorded fixture already covers, so waiting buys nothing this lane does not already have.
revisit ifkazi registers `portfolio`, at which point the fixture pin can be relaxed to trust the live schema directly
✗Fork or vendor kazi's portfolio schema as a separately-maintained spec dira ownsrefused This is dec-0008's "read kazi's internals directly" alternative wearing a schema instead of a database — it would couple dira to a copy of kazi's shape that drifts independently of kazi's own source, which is worse than depending on a recorded fixture that at least states plainly which machine and which kazi version it came from.
This is dec-0008's "read kazi's internals directly" alternative wearing a schema instead of a database — it would couple dira to a copy of kazi's shape that drifts independently of kazi's own source, which is worse than depending on a recorded fixture that at least states plainly which machine and which kazi version it came from.
✗Drop by_repo and fleet_remote from the join entirely and derive everything from `status <ref> --json` alone, since that command is the one already registeredrefused dec-0008 already established the join is a hybrid because per-goal truth needs `status`, but blocked attribution (cause, blocker) and the planned/todo/blocked totals exist only on portfolio (dec-0008 §1).
Dropping portfolio would silently lose the one row only dira-plus-kazi together can produce, for no gain the maintainer's registration would not already give for free.