Skip to content

feat: Align open-security with @hasna/contracts - #4

Merged
andrei-hasna merged 3 commits into
mainfrom
factory/ed0d9396-105c-45fe-afee-e595d1f0-c78b613a
Jul 29, 2026
Merged

feat: Align open-security with @hasna/contracts#4
andrei-hasna merged 3 commits into
mainfrom
factory/ed0d9396-105c-45fe-afee-e595d1f0-c78b613a

Conversation

@andrei-hasna

@andrei-hasna andrei-hasna commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Objective

Align open-security with @hasna/contracts

Run the @hasna/contracts conformance check for this repo and fix every violation until it passes — ensure a valid hasna.contract.json, published_artifact_gate satisfied (artifact-scan wired into prepack), storage waiver where applicable, and all required metadata/scripts present. Keep changes minimal and conformant. Open a PR; do not merge.

Verification

  • policy source: base 1742c71 (immutable commit — agent-proof)
  • ⚠️ GATE-INTEGRITY: agent touched verify-bearing config — REVIEW (scripts.artifact-scan, scripts.contracts:check, scripts.prepack)
  • containment: env — allowlist env, non-login shell, run-scoped HOME (registry auth seeded for install)
  • install: pass
  • typecheck: pass
  • lint: FAIL
  • build: pass
  • test: pass
  • doctor (ci): ok — 11 checks passed (1 advisory)

Run run_6e30283fde98 · backend codewith · task ed0d9396-105c-45fe-afee-e595d1f02c31
🏭 Generated by @hasnaxyz/factory


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Align open-security with @hasna/contracts

Run the @hasna/contracts conformance check for this repo and fix every violation until it passes — ensure a valid hasna.contract.json, published_artifact_gate satisfied (artifact-scan wired into prepack), storage waiver where applicable, and all required metadata/scripts present. Keep changes minimal and conformant. Open a PR; do not merge.

X-Factory-Run: run_6e30283fde98
X-Factory-Task: ed0d9396-105c-45fe-afee-e595d1f02c31
…acts gate

The manifest added by this PR was not a hasna.service_contract.v1 document:
all five required fields (schema, name, class, contractVersion, kitVersion)
were absent, and the three fields it did write (version, package, waivers)
are rejected as unknown keys by the strict schema. Because the file is listed
in package.json `files`, npm publish shipped that invalid manifest to every
consumer.

- hasna.contract.json: real v1 shape for the cli-with-store class shield
  actually is — bins, user-hosted story, the local SQLite boundary
  (HASNA_SHIELD_, ~/.hasna/shield/shield.db), the cli/mcp/sdk surfaces it
  ships, and metadata.release.artifactScan pointing at the artifact-scan
  script prepack already reaches. The API surface is declared `deferred`
  with a reason: shield-serve does not answer GET /health, /ready, or
  /version, so declaring it supported would assert endpoints that do not
  exist.
- Drop the storage waiver. It could never apply: sqlite is not in
  WAIVABLE_STORAGE_ENGINES, and a cli-with-store repo shipping shield-serve
  is refused a postgres waiver outright, so the declaration would be
  silently ignored while reading as an approved exception.
- contracts:check invoked `@hasna/contracts check`, which is not a
  subcommand in any published version — the gate could only ever fail with
  "unknown command". It now runs the documented repo self-check
  (`contracts repo-conformance .`), and a new contracts:manifest script runs
  `contracts validate hasna.contract.json`. Both resolve the binary from a
  pinned @hasna/contracts devDependency so the gate is reproducible from the
  lockfile instead of from whatever a package runner resolves at run time.
- Enforce contracts:manifest in CI and cover the manifest in the test suite
  (src/contract-manifest.test.ts) against the real ServiceContractManifestSchema,
  so the repo cannot drift from the kit it claims to track. 7 of the 8 new
  assertions fail on the manifest this commit replaces.
- docs/contract-conformance.md records the four capability gaps that keep
  contracts:check non-zero (no PostgreSQL engine, no health topology, no
  self-host artifact, hand-written SDK) instead of hiding them behind a
  waiver conformance would ignore.
`storage.sqlitePath` named `~/.hasna/shield/shield.db`, which is not the
store: `getDbPath()` resolves `~/.hasna/security/shield.db`, and the
`~/.hasna/shield` path is a legacy migration source that is copied FROM
and never written to. The manifest ships inside the published tarball, so
fleet tooling that reads `hasna.contract.json` to locate each app's
SQLite file got the wrong answer for shield alone — a backup pass would
open a file that exists on no current install and report an empty success,
and a restore written there is silently ignored whenever the real store
already exists.

The test named for that boundary asserted only `toEndWith(".db")`, and
the schema checks nothing more, so an arbitrary wrong directory passed
both gates. It now resolves the path the CLI would use under a throwaway
HOME with no `SECURITY_DB` or storage-mode override and compares it to
the declaration, so the two cannot drift apart in either direction.

- hasna.contract.json: sqlitePath -> ~/.hasna/security/shield.db
- docs/contract-conformance.md: same correction, and say why the legacy
  path is not the store
- src/db/database.ts: export `resolveDbPath()` so the declaration can be
  checked against the resolver without opening the shared connection
@andrei-hasna
andrei-hasna merged commit 233ae82 into main Jul 29, 2026
2 checks passed
@andrei-hasna
andrei-hasna deleted the factory/ed0d9396-105c-45fe-afee-e595d1f0-c78b613a branch July 29, 2026 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant