Skip to content

[Proposal] Mechanize the configuration contract: five-way sync check, provenance script, and a discipline ledger #213

Description

@liwen-aaa

Summary

AGENTS.md already states the repo's core stance: "Do not rely on prompts for runtime invariants" and "The runtime owns enforceable facts." Yet the Package configuration contract — the repo's own load-bearing promise — is enforced entirely by prompts. This proposal closes that gap by mechanizing three specific promises, in the same style as the existing drift guard (which proves the approach works): a five-way sync check for user-selectable config, a runtime-provenance script, and a lightweight append-only discipline ledger.

Scope guardrail up front: this is not a workflow engine, an orchestration layer, or a meta-framework. It is 2–3 small scripts that turn already-written prose promises into runnable checks.


Background: the contract is already written

AGENTS.md:75 (Package configuration contract):

A user-selectable model, feature toggle, permission, concurrency limit, theme/UI preference, or other package-owned choice must update extensions/setup/, extensions/shared/setup-config.ts, the no-argument /openpi-setup status output, SETUP.md, and the canonical defaults and prose in README.md.

AGENTS.md:79 (runtime provenance):

Before diagnosing installed behavior, provider compatibility, a manual Pi smoke, or any UI result, … Prove both the checkout revision and the single OpenPI source reported by pi list before reasoning from source code.

Both are unenforced prose today. A contributor adding a config option must remember five touch points by hand; a maintainer must review all five by eye.

The gap: contract vs enforcement

Promise (AGENTS.md) | Enforced today? | Evidence -- | -- | -- Tool classification (child-safe / excluded), fail-closed | ✅ Yes — drift guard | tests/extensions/shared/child-session.test.ts (source-scan, reaches factory registrations) Pi host packages stay peers, not bundled | ✅ Yes | tests/extensions/setup/package-contract.test.ts bun run check / test exist and run every round | ✅ Yes (CI) | .github/workflows/ci.yml Both test suites must be non-empty | ✅ Yes | scripts/run-tests.mjs Five-way sync for config options (AGENTS.md:75) | ❌ No — prose only | no test or script references SETUP.md / README.md as config-consumer contracts Runtime provenance (AGENTS.md:79) | ❌ No — prose only | no script exists as any last resort (AGENTS.md) | ⚠️ partial — lint disabled (noExplicitAny: off); 11 occurrences in tests/ today | biome.json

Impact

Before

  • Adding a config option: contributor must remember 5 touch points; maintainer must eyeball all 5 in review. Nothing catches a miss except a user discovering the knob is undocumented.

  • Diagnosing a runtime issue: "read the README section and prove provenance" is a prose step that gets skipped under time pressure — exactly the D-02 failure shape (a requirement written in text is accepted to be skipped).

  • New contributors cannot tell which promises are actually enforced: the repo looks fully mechanized (drift guard, package-contract) while the soft contracts are unguarded.

After

  • A config field missing from docs fails bun run check — the miss is caught in the same round it is introduced, not in a user support thread weeks later.

  • Provenance is one command; the diagnostic path starts from verified facts.

  • The ledger makes enforcement status visible: green rows are real mechanisms, prose rows are explicitly marked as trusted-to-skip.

Cost

  • ~2 small Node scripts (no new deps), ~1 appendix doc. Adds a few seconds to bun run check (well within the 20-min CI budget).

  • Review overhead of the proposal itself is the main cost; the ongoing cost is near zero because the checks are append-only additions to the existing check script.


Acceptance criteria

  • scripts/check-config-contract.mjs exists, runs in bun run check, and:

  • fails when a field in setup-config.ts is absent from all of SETUP.md / README.md / extensions/setup/ (fixture-based test included),

  • fails when a doc references a config knob absent from the field table,

  • passes on the current tree (no existing field is orphaned — if any is, the fix is to document it, not to weaken the check).

  • scripts/provenance.mjs exists and prints checkout revision + pi list source + match verdict.

  • (Phase 3) docs/disciplines.md exists with the enforcement-status table and an append-only check wired into check.

  • All existing tests and bun run check stay green.


Open questions

  1. Doc-coverage semantics: presence-based (grep) vs semantic (does the doc actually explain the knob)? This proposal starts presence-based (machine-checkable) and leaves semantic quality to human review — confirm that's acceptable.

  2. Where should the ledger livedocs/disciplines.md or root DISCIPLINES.md? (The repo currently has no such file; docs/ is the natural home.)

  3. Should the provenance script also be exposed as a pi skill (pull-based, so agents invoke it before diagnosing), or is a plain script enough for the first cut?


Related

  • (Windows test-suite issue): shares the same root cause (CI only runs Linux, prose promises unguarded) and the same fix pattern (small scripts + explicit status).

  • .gitattributes proposal: another first-day contributor-experience fix, independent of this one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions