Skip to content

T-QGMQ-vault-facilities-decision

State: planning/proposed · Impact: medium · Complexity: small

Agent Manager wants the vault to know it is a git repository and offer a validated commit, and polish already wants its own pre-commit schema check — two experiences wanting the same kind of platform facility, with no settled answer for where that logic lives or how two experiences contribute one commit-time check without either owning it. This task decides the placement once, so the Stage 5 git tasks build against a named shape instead of inventing their own.

LocationRole today
solutions/determined/crates/determined-core/src/ctx.rs#CtxBundles vault_dir, repo_root, state_dir, http, jobs, engine, vaults per call; jobs/engine are the only boot-injected Arc<dyn Trait> fields today, added explicitly rather than through a service locator
solutions/determined/crates/determined-platform/src/backends/mod.rs#polishThe port-trait pattern: 17 capabilities dispatch through a macro-generated ports::XPort accessor gated by Capability/Backend (Node/Shadow/Rust); polish, vault_notes, media, ocr are hand-written exceptions because they were never TypeScript apps with a node arm to migrate from
solutions/determined/crates/determined-platform/src/openers.rsThe “no port trait, on purpose” pattern: platform-state surface (which apps are installed, how to launch one) constructed inline as SystemOpenerCatalog, deliberately outside Capability/Backend because it is registry state, not domain logic with two implementations
solutions/determined/crates/determined-platform/src/api/v1/agent_skills.rsA third, already-shipped pattern: determined_agent_skills::get_notes(&state.ctx(), ...) and its siblings are called directly, with no port trait and no Capability variant — the crate was Rust-native from the start, so there is nothing to migrate
solutions/determined/docs/planning/rust-backends/ARCHITECTURE.mdDocuments the port/Capability/Backend migration scaffolding for the 19 experiences that had a Node sidecar; its “why it has no port” table counts 12 endpoints (settings.rs, jobs.rs, vault.rs, health.rs) but omits agent_skills.rs, which also has no port for the same reason
packages/rust/dir-aspect/src/lib.rs#AspectDetects Git/Obsidian/Generic from marker directories; mirrored on the wire as determined-core/src/wire/mod.rs#VaultAspect. Nothing gates a facility on it yet
solutions/determined/crates/determined-platform/src/settings.rs#SettingsStorePer-namespace JSON store (get_namespace/set_namespace), the existing precedent for a per-vault “always ignore this rule” setting
solutions/determined/crates/determined-agent-skills/src/lib.rs#get_component_treeThe only check today that would refuse a commit — a discover-refusal — reachable only through the component-tree scan, not through any commit path
solutions/determined/experiences/polish/app/components/PolishSchemaValidationPane.vuePolish’s own frontmatter schema-validation pass (determined-platform/src/api/v1/polish_schema.rs), a second pre-commit-check candidate with no shared home either
solutions/determined/docs/decisions/A second, solution-local decision catalog (incrementing ids, D-0001–D-0024+) distinct from the root docs/planning/decisions/; this question spans agent-pants, determined and determined-platform, so it belongs in the root corpus per D-0002-entity-identifier-shape, not here

One decision, in docs/planning/decisions/, that:

  • Places the git status/commit logic as a plain domain crate (mirroring determined-agent-skills) called directly from a new determined-platform/src/api/v1/git.rs via Ctx — no ports::GitPort trait, no Capability::Git variant, no Backend toggle. Git has no Node predecessor to migrate from, so the port/Capability machinery (built for that migration) does not apply; it is domain logic over easy-git/fluent-git, not bare registry state, so openers.rs’s carve-out does not fit either.
  • Names a pluggable pre-commit validator mechanism: a new trait, Ctx extended with a boot-injected Vec<Arc<dyn ...>> following the same shape as JobSink/EngineProbe, so agent-pants registers its discover-refusal check (promoted out of get_component_tree into a standalone check_vault) and polish registers its schema validation, with neither owning the hook.
  • Names the ignore-store: a SettingsStore namespace, keyed per rule id and scoped per vault, holding “always ignore” choices; “ignore once” is UI/session state, never persisted.
  • States that this decision, not solutions/determined/docs/decisions/, is the home for the question, because it spans agent-pants, determined and determined-platform.
  1. Compare the three integration shapes already in the codebase against git’s needs: the port/Capability/Backend pattern (built for Node-to-Rust migration — does not apply, git has no Node arm), the openers.rs “no port trait, on purpose” pattern (platform registry state — does not fit, git status is domain logic over a git primitive crate), and the agent_skills.rs direct-call pattern (a Rust-native domain crate with no migration story — the closest fit). Record the choice and the reasoning.
  2. Design the pluggable-validator trait’s shape (method signature, what it returns — a list of warnings the caller can ignore vs. refusals it cannot) and where Ctx carries the registered list, extending the JobSink/EngineProbe boot-injection precedent. Open decision: whether registration happens in AppState::new directly or through a small builder, given the number of experiences expected to register (two, to start).
  3. Name the settings namespace and per-rule key shape for the ignore-store.
  4. Mint the id: takenIdChars('docs/planning/decisions', 'D') then mintBase36(<slug-seed>, taken) (solutions/ontological/lib/model/identifier.ts); hand-write frontmatter matching docs/planning/decisions/D-0002-entity-identifier-shape.md’s shape (see D-A27T’s frontmatter for a worked example) — sdlc ships no decision noun, so this is the one entity type authored by hand rather than through a create verb.
  5. Write the decision body (Context, Decision, Why, Options considered — the three shapes from step 1 — Consequences, Migration, Open questions), citing the Today-table locations as evidence.
  6. Correct solutions/determined/docs/planning/rust-backends/ARCHITECTURE.md’s “why it has no port” table: it counts 12 port-free endpoints but omits agent_skills.rs; add it and note the new git.rs will join it for the same reason.
  7. Verify: sdlc entities validate docs/planning/decisions/D-<id>-*.md.
AreaNote
docs/planning/decisions/D-<id>-vault-facility-placement.mdThe decision: placement, the validator trait, the ignore-store
solutions/determined/docs/planning/rust-backends/ARCHITECTURE.mdAdd agent_skills.rs (and the coming git.rs) to the “why it has no port” table
  • AC-1: docs/planning/decisions/D-<id>-vault-facility-placement.md exists, its id was minted with mintBase36 against takenIdChars('docs/planning/decisions', 'D') (no collision with an existing decision id), and sdlc entities validate passes on it.
  • AC-2: The decision names the git facility’s crate/module and its Ctx/api/v1 shape, and states explicitly that it carries no ports::GitPort trait and no Capability::Git variant, with the reasoning against both the port/Capability pattern and the openers.rs pattern.
  • AC-3: The decision names the pre-commit validator trait, its Ctx registration point, and lists agent-pants’ discover-refusal check and polish’s schema validation as its first two registrants.
  • AC-4: The decision names the ignore-store’s settings namespace and its per-rule key shape.
  • AC-5: solutions/determined/docs/planning/rust-backends/ARCHITECTURE.md’s “why it has no port” table lists agent_skills.rs alongside the existing four rows.
  • Implementing the git status service, the commit op, or either validator — T-NS6Z-vault-git-status-service and T-L7YP-git-panel-commit-with-validation build against this decision, they are not decided here.
  • Amending solutions/determined/docs/decisions/ (the solution-local catalog) — this question is cross-solution and lives in the root corpus instead.
  • Choosing the shell composable’s exact name or file — a one-line consequence of this decision, finalized by the task that writes it.
  • none

From the user’s Agent Manager planning request of 2026-09-07: git awareness as a vault facility was one of the eight brain-dump areas, and the same request separately wanted polish’s schema validation pluggable at commit time — two experiences wanting one commit-time hook. Grounded in the assessment solutions/agent-pants/docs/vault/design/workflow-and-ux-assessment.md. Member of M-BMFD.


← Back to Tasks