Releases: Kemetra/Seshat-BI
Release list
Seshat BI v2.1.0
Seshat BI -- v2.1
This note summarizes the changes merged after v2.0.0. The complete per-entry
record, including specification and pull-request references, lives in
CHANGELOG.md.
Why this is 2.1 and not 3.0
This is a MINOR release under
docs/operations/versioning-policy.md. It registers two additive rule IDs
(DL10 and DL11) and adds the optional seshat check --explain surface.
Existing commands, flags, default text, exit meanings, and rule IDs remain in
place.
The new design rules can report errors on design artifacts that were previously
ungoverned. That is the policy's explicit MINOR case: a new contract is introduced
in a new version rather than changing the meaning of an existing rule ID.
No migration is required for repositories that do not use the newly governed
design or two-table comparison surfaces. Consumers parsing seshat check output
continue to receive the v2.0 default shape unless they opt into --explain.
Governed actual-to-target ratios
Spec 156 (#711, #712) closes the mismatch between the sanctioned
variance-vs-target contract and the measure generator.
binds_toremains the scalar primary authority.- A sibling
compares_toblock names the governed target Gold table and columns. - One stdlib-only validator is shared by approved inventory and DAX generation.
- Numerator and denominator tables must align with their respective bindings, and
every source/filter column must be declared by the correct side. - Comparison PII is effective PII for finalization and statistical policy.
- Statistical columns remain attached to their own source table.
Malformed table/column identifiers, a bare gold. prefix, or non-string filter
operators are refused before generation. DAX output remains text only: Seshat does
not write a PBIP, connect to Power BI, or grant an approval through this feature.
Evidence dates without invented freshness
Spec 157 (#712) gives readers the dates needed to judge whether an answer is
current without manufacturing a freshness verdict.
Source profiles disclose the reporting date, coverage end, and committed-evidence
observation date when those facts are parseable from committed evidence; an
unprovable value is an explicit GAP. The optional answerability summary carries
exactly three cited dates and Publish Ready guidance explains how to present them.
No new readiness field, freshness threshold, badge, score, or approval is created.
Findings explain themselves at the failure point
seshat check --explain (#706) renders the existing, governed means and fix
text from docs/rules/rule-fixes.yaml beneath each ordinary text finding.
The default finding line is byte-identical with and without the feature, and the
flag changes neither severity nor exit code. JSON, review, and SARIF formats refuse
the unsupported combination rather than pretending guidance was included.
Design references and vocabulary become checkable
Two new rules ship in #707 and #708:
DL10reconciles the page-section vocabulary across the authoritative desktop
grid, mobile grid, dashboard-page template, and filled report blueprints.DL11resolves the design file and token pointers whose grammars are actually
machine-checkable, while deliberately excluding prose and store identifiers.
The follow-up also makes a fresh seshat scaffold-design pass the rules it emits:
referenced spec targets are packaged and scaffolded, and corpus membership is
derived from the real scaffold set.
Business questions reach the named owner
Across the twelve retail KPI domain packs, the governed layer now carries forty-one
owner-question cards (#709). Each card states the question, the silent failure if
unanswered, the layer default as context only, and the existing critical Decision
Store type that records the answer. The cards grant nothing: unanswered meaning
remains pending and no default is converted into a ruling.
Reliability and operator guidance
- A zero Power BI MCP session deadline now stalls before any transport read (#702),
fixing a Windows clock-boundary defect that could consume a frame despite a
caller's zero wait budget. - Idea-engine candidates use assigned schema-validated IDs rather than fuzzy title
reconstruction, and its model effort tier no longer requests an unsupported
configuration (#703). ONBOARDING.mdnow routes a new arrival into the existing Seshat BI entry points
instead of presenting one maintainer's usage telemetry (#704).- README, Studio, F016, and adopted-idea status claims are reconciled with the
shipped tree (#710-#712).
Publication surfaces
The coordinated release projects one owner-approved 2.1.0 version into the
Python package, the scoped and unscoped npm packages, Claude repository marketplace
metadata, and the generated Claude/Codex bundles. GitHub Release, PyPI, npm, and
repository-plugin availability are verified independently after publication.
Public Claude and OpenAI discovery-catalog submissions remain separate
identity-verified human actions; repository marketplace availability does not imply
either public catalog has accepted a listing.
Seshat BI v2.0.0
MAJOR release. Two existing CLI contracts changed. If you script against seshat, read this before upgrading.
Full detail: docs/releases/v2.0.md · per-entry citations in CHANGELOG.md.
Breaking
1. seshat doctor's default text output is reshaped (M8, #689)
# v1.1.0 — flat, one line per finding
[error] A1 <message> (<locator>)
# v2.0.0 — grouped by rule id
A1: 2 finding(s)
[error] <message> (<locator>)
hint: <non-mutating repair guidance>
next allowed action: <action>
Any consumer scraping doctor stdout will break. Migration: seshat doctor --format json — new in this release, emitting {"findings": [...], "finding_count": N} with a repair_hint per finding. Parse that; the text digest is a human surface and may be reshaped again.
2. seshat pbi-mcp preflight can now exit 2 where it exited 0 (spec 149, #659)
Server identity is now derived from the argument vector, not just name/command/url, and --readwrite=true is recognised as write mode. A .mcp.json could previously alias the official Power BI MCP server under an unrelated name, invoke it via npx in args, and classify as absent — handing the bypass guard a clean verdict while --skipconfirmation sat in the same entry.
This is a security fix, not a regression. If preflight newly exits 2, it is reporting a real bypass-shaped config that was previously invisible. Fix the config; do not pin to 1.1.0 to restore the 0.
What did NOT change
No seshat check rule id was added, removed, or renamed, and no existing rule's predicate or severity changed. src/seshat/rules/ has zero changed files in this range, and the registered id set is identical at both refs. A consumer's seshat check verdict on an unchanged repo is unaffected by this release — the blast radius is the two CLI contracts above, not the governance rule set.
Also in this release
- Studio governed analyst workbench (spec 140, #695) and Studio operations and client review (spec 141, #697). 141 guards a disclosure where 140 guarded a write:
contracts/export-boundary.mdseparates softening, leaking and acting. - Approval-gated Power BI MCP writes (spec 149, #659 + #670/#672/#674/#679).
plan-writeandapplyagainst Microsoft's official local server (external, unforked, never vendored, ADR 0018). Every precondition is derived, never accepted as a caller assertion; twelve typed gate blockers, fail-closed. A successful write advances no readiness stage and grants no approval, and--skipconfirmationis refused everywhere. - Guided setup execution (spec 155) and capability derivation from committed evidence (spec 153).
seshat doctor --format json, grouped findings, non-mutating repair hints, next-allowed-action (M8). Hints are text only — nothing is executed on your behalf, anddoctorstill never modifies a file. It remains advisory:seshat check's exit code is the only gate.- The unit suite now runs on Windows in CI (#698, #699). Previously Windows CI ran only the CLI first-success journey and never invoked
pytest, so POSIX-locked fixtures were invisible by construction (#691). Non-blocking while a baseline accumulates.
Install
pip install seshat-bi==2.0.0
Also on npm as @kemetra/seshat-bi and the unscoped seshat-bi.
Seshat BI v1.1.0
Seshat BI -- v1.1
This note records the changes merged after the frozen v1.0 release note. It
does not rewrite the historical claims captured in docs/releases/v1.0.md or
any earlier note.
The full per-entry detail (with spec and PR citations) lives in CHANGELOG.md;
this note summarizes the shape of the release.
The headline: Studio is installable for the first time
Read this before anything else in this note.
v1.0.0's published wheel carried no Studio frontend. Anyone who ran
pip install seshat-bi[studio]==1.0.0 got a seshat-studio console script that
fail-closed with "Studio frontend assets are missing." That defect was disclosed
honestly in docs/releases/v1.0.md and tracked as issue #623.
The fix (#636) merged roughly 11 hours after the v1.0.0 tag. Because the
tag is immutable and PyPI rejects re-uploading an existing filename, the fix
could not reach users through 1.0.0 at all -- a new version was the only
remedy. That is the reason this release exists.
scripts/build_studio_frontend.py now runs before packaging in both
release.yml and ci.yml, and the built assets ride in both the wheel and
the sdist (#641, #642).
Verified by building the artifacts and counting entries, rather than by reading
the workflow -- the tests that would catch this skip in the release job, so
a green CI run is not evidence for this particular claim:
WHEEL seshat_bi-...-py3-none-any.whl studio/static entries: 3 index.html: True
SDIST seshat_bi-....tar.gz studio/static entries: 3 index.html: True
The published 1.0.0 wheel scored 0 on that same measurement.
What else is in this release
Studio closes a technical approval round trip
Spec 139 Phase 6 (#625, #626, #632, #633) lands the half that v1.0 explicitly
disclaimed. A technical approval can be registered from a streamed turn,
decided exactly once with replays refused, relayed to the provider, and
returned to the browser with the readiness verdict attached.
The authority boundary has not moved, and this is the part to read
carefully. This is the technical approval lane only:
- Named-human approval authority is split from technical authority (T025).
- Readiness forbidden scope is read fail-closed (T025).
- Studio grants no business approval, moves no readiness stage, and
emits no confidence score. - Approving a readiness stage remains exactly what it was: a human edit to
readiness-status.yaml, read through the sameapproval_is_shape_validthe
gate rule uses.
Studio also now lists the business decisions a named human still owes (T027,
#635). That is a read-only ledger of who owes what -- not a surface that
decides any of them.
Supporting fixes
agent_turnsis derived from what the build can actually do (#638),
not advertised statically, and is pinned in both directions by
tests/unit/test_studio_capability_truthfulness.py.- A turn paused on an approval now outlives the stalled-provider timeout
(#630). - The approval delivery seam is reachable in production, not from tests only
(#628).
Governance and docs
Seshat Studio is classified in the authority taxonomy as a Product Module
(#627); Core remains functional without it. Phase 6 was re-verified against the
merges that closed it (#631), and T033 (#643) and T023 (#645) were closed on
recorded acceptance evidence.
What this release does NOT do
- Studio is still not finished. It remains behind the optional
studio
extra, and a basepip install seshat-biinstalls no FastAPI/Uvicorn.
Runningseshat-studiowithout the extra prints a named diagnostic naming
both install lanes rather than anImportErrortraceback (FR-006). - No business-approval surface ships. See the boundary above.
- T032, T036, and T037 of spec 139 remain open. T036 needs an external
signed-in Codex subscription and a real browser; T037 is an independent
review of the completeness claim. Both are owner-gated by design and cannot
be self-certified by the agent that built the work. T032's accessibility
suite now runs and gates in CI (#647), but the box is the owner's read. - No verb, rule id, exit code, or required-argument change. The audited
policy surfaces are unchanged from v1.0.0; all source change in this release
is confined tosrc/seshat/studio/and is additive.
Seshat BI v1.0.0
Seshat BI -- v1.0 release candidate
This candidate records the changes merged after the frozen v0.8.2 release note.
It does not rewrite the historical claims captured in docs/releases/v0.8.md,
docs/releases/v0.8.2.md, or any earlier note.
The full per-entry detail (with spec and PR citations) lives in CHANGELOG.md;
this note summarizes the shape of the release.
The headline boundary: Studio ships as an INCOMPLETE PREVIEW
Read this before anything else in this note.
This release ships the first installable slice of Seshat Studio -- a
localhost analyst console (spec 139) -- and Studio is not finished. It is
published now, deliberately and knowingly, so the 86 commits behind it stop being
invisible to installed users; a second release follows when Studio completes.
What that means concretely, for anyone who finds the seshat-studio console
script in an installed 1.0.0:
- Studio has no approve, apply, or reject surface. By design, not by omission.
Spec 139 Phase 4 ships the read/observe half only. There is no handler in
src/seshat/studio/that grants an approval or applies a change. Approval
remains exactly where it was -- a human edit toreadiness-status.yaml, read
through the sameapproval_is_shape_validthe gate rule uses. - The Codex bridge has no production caller.
CodexBridgeand itshealth()
path are shipped, tested, and reachable only from tests; no CLI verb or
endpoint drives them. This is tracked as open issue #618, "wire CodexBridge
into startup, behind an off-event-loop turn drain," which this release does
not close. Do not read "Codex integration" into this release as a working
user-facing feature. - Studio is behind an optional extra and is absent from a base install. A
plainpip install seshat-biinstalls no FastAPI/Uvicorn. Running
seshat-studiowithout the extra prints a named diagnostic naming both install
lanes, not anImportErrortraceback (FR-006). - The published wheel carries NO Studio frontend, so
seshat-studiois not
usable from PyPI in this release (issue #623).release.yml's
build-validatejob builds the wheel without running
scripts/build_studio_frontend.py, andsrc/seshat/studio/static/is
gitignored generated output -- so there is nothing forpyproject.toml's
artifactsre-include to collect. Measured on a wheel built exactly the way
the release job builds it: 0studio/staticentries, while the
seshat-studioconsole script ships. This fails closed, not blank:
describe_missing_assetsreports the missing build with a recovery action
rather than serving an empty workspace. CI being green is not evidence against
this --ci.ymldoes build the frontend, so the wheel-content tests run and
pass there, while inrelease.ymlthey never run at all
(tests/unit/test_studio_frontend_build.py:39skips without the build output).
Tracked for the Studio completion release, when a working UI is the point.
Nothing in Studio grants an approval, moves a readiness stage, or emits a
confidence score. The governance boundary this kit exists to enforce is
unchanged by it.
Why this is a MAJOR release
Short version: two independent breaking CLI contract changes force the MAJOR
row -- see "TWO changes hit the MAJOR row" below, which is the section that
decides the number. The additive inventory in this section is what the release
adds; it is not what sets the version.
This candidate carries 86 non-merge commits across 27 merged pull requests --
31 feat, 26 fix, 14 docs, 10 refactor, and the remainder
build/test/style/ci.
The 27 is deliberately not the count of #-references in commit subjects, which
is 31: four of those references are issues, not pull requests (#618 among
them). Each of the 27 was confirmed to resolve as a pull request via the GitHub
API rather than inferred from the (#N) squash-subject convention.
Measurement cutoff: those totals are v0.8.2..18492bc -- from the commit
tagged v0.8.2 to the merge of PR #620, which was the head of main when this
inventory was taken. They deliberately exclude the release-preparation commits
that follow, including the commit that adds this note and the version
projection commits prepare-coordinated-release creates afterwards. A count
stated inside the release it counts cannot include itself, so the cutoff is named
here rather than left for an auditor to infer.
Two additive surfaces would, on their own, have put this on the MINOR row of
docs/operations/versioning-policy.md:
- A new console script,
seshat-studio. Deliberately outside the
seshat/retaildispatch chain, so it adds no subcommand to an existing verb
and changes no existing verb's behavior. That is the policy's "NEW CLI verb,
no change to existing verb behavior" row. - A new public subcommand,
seshat spec-status [--fix](64993f8),
registered insrc/seshat/cli/parser_core.pywith a production handler and a
capability entry. Absent atv0.8.2; same MINOR row.
The full verb inventory was diffed rather than sampled --
add_parser("...") across parser.py and parser_core.py goes from 40 verbs
at v0.8.2 to 41 at HEAD, with spec-status the only addition and nothing
removed.
No new seshat check rule id was registered in this release, and the rule-set
growth row does NOT apply. This is stated explicitly because the diff invites
the opposite reading: git diff v0.8.2..HEAD --name-status -- src/seshat/rules/
reports 44 files, every one M, zero A. Those 44 modifications are the
rule-coverage migration (#589, #590) and are declaration metadata only --
each adds a Requirement/corpus declaration and, where applicable, a
requires=(...) entry plus a ReportsItsOwnAbsence note, so the framework can
distinguish "this rule was silent because the repo is clean" from "this rule was
silent because it never found its input." No rule predicate was broadened, no
new failure mode was added inside an existing rule id, and no severity moved
from warning to blocking.
That distinction is load-bearing, so it was measured rather than assumed: the
policy's MAJOR row covers "a broadened predicate, a new failure mode inside an
existing rule id," and 44 modified rule files would otherwise be the shape of
exactly that. A repo that was green on 0.8.2 is judged identically by these 44
rules on 1.0.0.
TWO changes hit the MAJOR row -- and they are why this release is 1.0.0
Both were found by external review on the release PR (#622), not by the
automated gates. They are independent: a consumer can be broken by the second
without ever invoking the four verbs in the first.
Breaking change 1 -- four PBIR verbs gain two required flags
1ac28b5 makes --repo and --table newly REQUIRED on four verbs that
already shipped in published v0.8.2, and their handlers return exit code 2
when the new gate refuses. The verbs are pbir-apply-theme,
pbir-format-visual, pbir-set-page-background, and pbir-set-geometry.
Measured, not inferred:
- All four verbs are present in
v0.8.2:src/seshat/cli/parser.py. _add_pbir_authoring_gate_argumentsdoes not exist atv0.8.2-- the two
flags are new, and both carryrequired=True.- So a script that ran
seshat pbir-apply-theme --theme X --report Yagainst a
published 0.8.2 install fails with an argparse error after upgrading, and a
gate refusal now exits2where the command previously proceeded.
docs/operations/versioning-policy.md classifies this on the MAJOR row: "A
CLI verb's existing flag/output contract changes (e.g. ... a flag is removed or
renamed, an exit-code meaning changes) -- Breaking for any consumer/script
parsing that output."
Breaking change 2 -- pbi-mcp doctor exit code and JSON shape
seshat pbi-mcp doctor now exits 2 where v0.8.2 exited 0, whenever
prerequisites are unresolved. Measured:
- At
v0.8.2,src/seshat/cli/commands/pbi_mcp.pyended_run_doctorwith
return 2 if rec.blocked else 0. - On HEAD (line 146) it reads
return 2 if rec.blocked or rec.missing_prerequisites else 0. tests/unit/test_pbi_mcp_cli.pyrecords the flip directly -- an existing
assertion moves fromassert code == 0toassert code == 2, and a new
test_doctor_exits_two_for_unresolved_prerequisitespins it.
So seshat pbi-mcp doctor --intent published-query --json returns 0 on a
published 0.8.2 install and 2 on 1.0.0 for the same repository state. Any
automation treating this advisory command's zero exit as "success" breaks --
and it never touches the four PBIR verbs above.
The --json payload also gains six fields (target,
target_semantic_model_ready, dashboard_ready, dashboard_ready_tables,
dashboard_design_approval, official_report_skills). Additive for a tolerant
reader, but it is an output-shape change on the same MAJOR row, so it is recorded
here rather than left for a consumer to discover.
Migration: pbi-mcp doctor is advisory -- treat a 2 as "prerequisites
unresolved," not as a hard failure. Automation that gated on exit == 0 should
read the JSON payload's own status fields instead of the process exit code.
The exit-code sweep, so this list is complete
After the second finding, every changed return-code line under src/seshat/cli/
and src/seshat/*.py was diffed rather than sampled. Exactly one existing
contract moved -- the pbi-mcp doctor pair above. The other changed returns are
in new code paths: spec_status.py is a new verb (documented above), and
integrations.py only gains an optional --harness flag with no change to its
existing returns. No other verb's exit-code meaning changed.
Both are disclosed rather than buried, following the precedent
docs/releases/v0.8.md set for the HR1 gold_placement change. Unlike that
case, neither of these is a bug fix restor...
Seshat BI v0.8.2
Patch release. Full detail in docs/releases/v0.8.2.md and CHANGELOG.md.
Install
pipx install seshat-bi==0.8.2
Why upgrade
Trailing anomaly detection returned wrong answers. seshat analyze run with method.id: detect_anomalies and parameters.model: trailing_mad misclassified observations on v0.8.0 and v0.8.1. Nothing in the output signalled it: the run completed, wrote schema-valid evidence, and recorded outcome: computed. An installed user could not detect the defect from the tool and could not work around it. (PR #564)
_Baseline.residual already holds observed - center, but the flag compared residual - center against the threshold, so the deviation carried the series magnitude:
deviation = (observed - center) - center = observed - 2*center
On a level-112 series, a point sitting exactly on its own baseline center produced a deviation of -112 against a threshold of 5.19, and was flagged.
The misclassification runs in both directions, because the injected term is the baseline center:
- False positives. Two-sided on a level series: on a synthetic 48-week fixture the defect flagged 23 of 23 evaluated weeks; the corrected engine flags 1, the single injected excursion.
- False negatives.
direction: upperwith a positive center suppresses real excursions. For center112, threshold5.19, and a genuine deviation of+6, the correct comparison flags it while the defective comparison tests6 - 112 = -106and does not.
So this is not uniformly a fail-open. Depending on the declared direction and the series level, anomaly evidence from v0.8.0 or v0.8.1 may contain fabricated flags, missing flags, or both.
The seasonal_mad path masked the defect in testing, because it centers on STL residuals where the center is near zero. Only trailing_mad, which centers on raw values, scaled the error with the data.
The correction is not a single subtraction. The two baselines center on different quantities, so _Baseline now carries an explicit deviation computed per baseline: the trailing baseline's residual is its deviation, while the seasonal baseline's residual must still be taken relative to the residual center. Thresholding the seasonal residual directly would shift both two-sided and directional limits whenever the residual median is displaced from zero.
Two regression tests sit on the property rather than on an incidental number: a point at its own center is never anomalous, and adding a constant to every observation must not change any verdict.
Who is affected
Only callers of seshat analyze run with method.id: detect_anomalies and parameters.model: trailing_mad. The method needs the optional stats extra and a governed analysis specification citing an approved metric contract, so the reachable surface is narrow — but every such run on v0.8.0 or v0.8.1 returned untrustworthy flags.
Anyone who accepted anomaly evidence produced by v0.8.0 or v0.8.1 should re-run the analysis on v0.8.2 before citing it. The evidence files themselves remain readable; only the anomaly:<key> estimates were wrong.
Also in this release
- Every closed-catalog method now has an end-to-end worked example. Coverage went from one method (
describe) to all eight, addingdocs/worked-examples/statistical-forecast.mdanddocs/worked-examples/statistical-catalog.md. Both publish only numbers produced by committed fixtures, and integration tests assert those numbers, so engine drift breaks a test instead of leaving a page quietly wrong. - The closed method catalog marks required and optional parameters separately.
forecastrequires all ten of its parameters, includingfinal_periodandpartial_period_policy— the same two that are optional fordetect_anomalies. A contract test readsschemas/statistical-analysis-spec.schema.jsonas ground truth and fails when the prose disagrees in either direction. - A Contributor Covenant code of conduct (PR #563), completing the repository community health profile.
Release machinery
The npm package is now published from the same release leg as PyPI, with publish-npm declaring needs: publish-pypi. That guarantees ordering, not atomicity: three packages publish sequentially — seshat-bi on PyPI, then @kemetra/seshat-bi, then the unscoped seshat-bi alias — and no publish can be undone. See the per-package recovery table in docs/releases/v0.8.2.md.
All three packages are confirmed published at 0.8.2 for this release.
Verification
pytest tests/unit tests/contract— 4859 passed, 21 skippedpytest tests/integration/test_statistical_artifact_flow.py— 9 passedruff format --check src testsandruff check src tests— clean
Seshat BI v0.8.1
Patch release. Full detail in docs/releases/v0.8.1.md and CHANGELOG.md.
Install
pipx install seshat-bi==0.8.1
Why upgrade
The bundled governor MCP server no longer hangs. In v0.8.0, seshat_run_static_check never returned when the plugin ran the governor over stdio — over 11 minutes with no output, against a 12-second CLI baseline for the identical check. One of the six governor tools was unusable for anyone who installed the plugin, with no workaround. (#557, PR #558)
subprocess.run(...) without an explicit stdin gives the child the parent's stdin. For seshat mcp that handle is the live JSON-RPC pipe from the client: git inherited it and blocked reading it, while the parent blocked in communicate() waiting for git — and the pipe could only be fed by the MCP client, which was itself waiting for the response.
Only that one tool hung, because it is the only governor tool that shells out to git. The CLI was never affected, because there stdin is a terminal and inheriting it is harmless — which is the whole 12-seconds-versus-forever gap.
Fixed with a single gitutil.run_subprocess helper (stdin=DEVNULL plus a default timeout, so a residual stall fails loud rather than hanging), with 11 governance call sites routed through it. The dbt/dagster execution runners are deliberately excluded: they invoke user builds that legitimately outlive the shared cap and are not reachable from the read-only governor tools.
Covered by a regression test that spawns the real server and drives it over a pipe — the only shape that reproduces the defect, since the existing in-process tests return in 0.2s. Verified failing on the unpatched code before being trusted green.
Also in this release
- Four corrected facts in the public-catalog submission guidance (#556). The runbook is copied into an external portal under a verified identity, so a wrong path or capability answer is a submission defect. It cited plugin manifest paths at the repository root that do not resolve, told the owner to declare no MCP server when both bundles ship
seshat-governor, and gave a skill-count command that silently returned zero for the Claude bundle. The shipped Codex bundle README carried the same false "activates no ... MCP server" claim and was corrected at its template and regenerated.
What has not changed
- No new capability, verb, skill, or rule. Both bundles still carry 21 skills.
- No governance behavior changed. No tool advances a stage, grants an approval, writes a readiness artifact, or emits a score.
- Spec 138 remains partially implemented — US2 and US3 delivered; US1, US4, and the external-acceptance half of US5 outstanding.
Note on MCP acceptance
This release fixes a defect in the bundled MCP server; it does not constitute external acceptance of that server. Spec 138 US1 (T021–T023) still requires operator-run verification in a clean workspace with no Seshat development checkout. Any public-catalog submission should declare the seshat-governor MCP server (local, read-only, stdio, no auth) and should not claim verified external MCP behavior.
Seshat BI v0.8.0
Minor release. Full detail in docs/releases/v0.8.md and CHANGELOG.md.
Install
pipx install seshat-bi==0.8.0
Headlines
- PBIP X-Ray —
seshat xraybuilds a model graph by resolving measure/column references across parsed TMDL, reads PBIR visual bindings, and reports findings X0–X4.seshat model-diffclassifies TMDL changes as semantic / cosmetic / additive / removed. Advisory and read-only: neither grants an approval, moves a readiness stage, or emits a confidence score. (#549, #550, #551) - The ten compass verbs now ship in the packaged bundles — the Claude and Codex bundles go from 11 skills to 21, behind a portability gate, with the capability inventory as the authored source of what ships. Spec 138 remains partially implemented (US2/US3). (#547, #548)
- A governed statistical evidence engine (
seshat analyze) — eight closed methods, strict schemas, immutable derived evidence, deterministic pending-human review. No result grants approval or changes readiness. (#529) - A headless TMDL doc-comment lint (
seshat tmdl-doc-comment-lint) — one rule: a///block must be followed by a declaration. Deliberately not a TMDL validator; a pass does not mean Power BI Desktop can load the model. (partial fix for #494) - Three further read-only surfaces —
seshat readiness-diff(#536),seshat cvd-evidence(#541), andseshat profileover a landed CSV/TSV/Excel file (#535).
Six new CLI verbs in total: xray, model-diff, readiness-diff, cvd-evidence, analyze, tmdl-doc-comment-lint.
One behavior change worth reading before upgrading
HR1 gold_placement now ERRORs on an unresolvable prefix (#499, #505), where it previously returned {} silently. This can newly fail a repo that was passing only because the resolution was empty.
Placement prefixes resolve against the physical bare dimension name. For a dimension declared gold.dim_product_rss, write dim:dim_product_rss.item — a schema-qualified dim:gold.dim_product_rss.item is parsed only up to the first . and will be rejected.
Classified under the bug-fix-restores-intended-behavior row of docs/operations/versioning-policy.md, which is why this release is MINOR rather than MAJOR.
Scope of this release
199 commits across 49 merged pull requests since v0.7.1, measured 363c41a..44bb00c — 158 non-merge commits (42 feat, 51 fix, 39 docs, 15 refactor). The cutoff excludes the release-preparation commits that follow it.
Spec 137 (the Finance GL genericity proof) landed in this window but ships no runtime change — it is fixtures, worked examples and mapping artifacts under mappings/, docs/worked-examples/ and benchmark/scenarios/, with no change to src/seshat/. It is evidence that the engine is not retail-specific, not a feature.
Provenance
Published to PyPI via Trusted Publishing (GitHub OIDC) with attestations, from the validated artifacts built at fc0015c. Public catalog listing (Claude plugin directory / OpenAI) is a separate owner action and has not been performed.
Seshat BI v0.7.1
Seshat BI -- v0.7.1 patch release candidate
This patch candidate records the single change merged to main after the frozen
v0.7 release note (docs/releases/v0.7.md). It does not rewrite the historical
claims captured there or in any earlier release note.
Why this patch exists
The v0.7.0 tag is frozen by the repository's v* tag-immutability ruleset and
points at a commit whose packaged seshat/pbi_mcp/scan.py trips the release
artifact inspector (scripts/inspect_release_artifacts.py). Because a protected
tag cannot be moved, v0.7.0 can never publish to PyPI. This patch carries the
inspector fix forward on a fresh, publishable version.
The v0.7.0 publish attempt failed closed: the build-and-validate job blocked
and the publish job was skipped, so no v0.7.0 artifact ever reached PyPI. Every
capability described in docs/releases/v0.7.md first becomes publicly
installable with this patch.
What this patch fixes
- Release inspector false positive blocking publication (PR #478): the
macOS-user-path detection pattern inseshat/pbi_mcp/scan.pyspelled the
literal byte shape/Users/...that the release inspector scans shipped
source for. The irony is structural --scan.pyis the secret scanner, and
the flagged string was its own detection regex for leaked macOS paths in
generated Power BI config, so the detector tripped on itself. No real path
leaked: the matched text was/Users/[^/, i.e. regex syntax, and a repo-wide
scan found exactly one hit. The pattern is now assembled from fragments so the
literal never appears in shipped bytes; the compiled regex is identical and
every detection case still fires. The inspector's regex is deliberately left
strict -- no release guard was weakened. This follows the v0.6.1 precedent and
a convention already used intests/unit/test_pbi_mcp_generate.py.
Honest boundaries
- This is a packaging-only patch: it carries no functional code, schema, or
CLI-behavior change. The compiled detection pattern is byte-for-byte
equivalent to the one it replaces, soseshat pbi-mcprefuses exactly the
same generated content it refused before. Every capability claim in
docs/releases/v0.7.mdcontinues to apply unchanged. - Publication evidence is not asserted here. This candidate does not itself
create a tag, publish to PyPI, create a GitHub Release, or submit to public
Claude, Codex, or OpenAI catalogs. External marketplace publication and the
GitHub Release object remain separate owner actions.
Seshat BI v0.5.2
Seshat BI v0.5.2 — a new dashboard capability plus a batch of security and hardening fixes.
Highlights
seshat dashboard(#358): writes a self-contained, static HTML readiness view of the workspace — a Home page with portfolio KPIs and one card per table showing the seven-stage readiness track — from the recomputedreadiness-status.yaml. No server, no external assets, theme CSS inlined, every value HTML-escaped; can write-and-auto-open. A read-only view of already-computed state — it fabricates no evidence or approvals.- Three credential-leak paths closed in dagster/portfolio redaction (#362, #364): a reformatted, schemeless driver error naming only the host/user of a
DATABASE_URL-shaped secret could survive the whole-value replace — URI-component decomposition now scrubs each part. - Explicit secret-key set for dagster redaction (#357, #363): a POSITIVE
ANALYTICS_DB_*credential set replaces the prefix scan, so config words (e.g.ENGINE=postgres) are no longer over-redacted while credentials stay scrubbed. seshat-initwriter hardening +init-projectlayout (#356) and thescaffold-sourceTOCTOU race (#345) — the follow-up tracked from v0.5.1 — are closed. The dagster command family now loads the workspace.env(#354).
Internal
- One shared URI-redaction core (
seshat/redaction_core.py) imported by the dbt, dagster, and portfolio redactors — pure refactor, no behavior change (#365).
Full detail: docs/releases/v0.5.2.md and CHANGELOG.md.
Install: pip install seshat-bi==0.5.2
Seshat BI v0.5.1
Seshat BI v0.5.1 — a patch release with two bug fixes and one enhancement.
Highlights
seshat scaffold-source <table>(#339): pip-only workspaces can now produce the first Source-Ready artifact without the development repository. The three Stage-1 blank templates ship as wheel package data; the scaffolded readiness passes the RS1 governance gate as an honest unstarted journey.validate/drift/value-checkhonor the workspace.env(#340): the live commands now loadANALYTICS_DB_*(and engine selection) from the gitignored.envexactly as the tool instructs — no more "no database connection configured" for a correctly-populated.env. No new dependency; malformed/invalid settings fail clean.dbt plansurfaces the underlying parse error (#341): a failed non-database PARSE no longer emits an emptyDBT_ARTIFACT_INTEGRITY:— the real Compilation Error now reaches the operator.
Full detail: docs/releases/v0.5.1.md and CHANGELOG.md.
Install: pip install seshat-bi==0.5.1
Follow-up tracked: #345 (scaffolder TOCTOU race, out of scope).