Skip to content

platform-objects: sys_setting_audit declares old_hash / new_hash as SHA-256, but a secret row carries the provider's keyed hmac-sha256 digest — re-describe both formats #26603

Closed

Description

@objectstack-fleet

Filing gate: ① a declaration defect with a named landing. The column metadata states a digest format the runtime does not write for secret rows, and an agent or admin reading the field metadata is told the wrong format. Found while landing #26534 (PR #26600, out_of_scope_findings, "arm (b)'s surface, which the seat holds"). Filed by the domain:server seat 2 (session_0186vfjHHMsRXC9EUT9hTFMo). ⛔ Not a claim. Dedupe: the newest 100 issues of every state grepped for sys-setting-audit.object, old_hash … description and hmac-sha256 … description → only #26534 and PR #26532. Reader: domain:server seat (platform-objects system objects).

Measured on main: packages/platform-objects/src/system/sys-setting-audit.object.ts says:

  • :140, TSDoc: "Format: hex SHA-256 of the canonicalised JSON";
  • :147, old_hash.description: "SHA-256 of the previous value (canonicalised)";
  • :155, new_hash.description: "SHA-256 of the new value (canonicalised)".

What the runtime writes:

The platform twin sys-platform-setting-audit.object.ts:137-149 already says "Digest of the … value. Never the plaintext." and states no algorithm. The generated en translation bundle carries the same SHA-256 strings.

  • Reach: the field descriptions are the object's published metadata, which /meta serves and Studio and agents read. Measured once, the description names an algorithm that secret rows never carry.

Business reason: an operator or an AI agent that checks an audit row against its declared format will judge every secret row malformed, or will try to match a secret's SHA-256 against the trail. That second case is exactly the offline guess the keyed digest exists to prevent. The declaration should state what is written.

Wanted: re-describe old_hash and new_hash (TSDoc and description) on sys_setting_audit:

  • a non-secret value: sha256: + hex SHA-256 of its canonical JSON;
  • a secret value: the crypto provider's keyed digest (hmac-sha256:…), never an unkeyed hash;
  • null as today, plus null for a secret when no keyed digest is available.

Align the platform twin's wording, then regenerate the translation bundles with the repo's generator. ⛔ No column type, length or name change.

Acceptance: both objects' old_hash / new_hash descriptions name both formats; git grep -n "SHA-256 of the previous value" -- packages/platform-objects returns only the regenerated bundles' new wording, or nothing; the platform-objects tests and the i18n bundle checks pass. Size: XS. Clause-②: the dev declares it (description only; no accepted or emitted value moves). Metadata-protocol: the dev measures it (a field description change on two system objects).


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 27, 2026
  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: audit line · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T10:57Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • Triage: lands in packages/platform-objects/src/system/sys-setting-audit.object.ts and its platform twin (the column descriptions); rationale: p3 · domain:server. State the format each row really carries: SHA-256 for plain values, the provider's keyed HMAC-SHA-256 for secret rows. Description text only, ⛔ no change to what is written.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 4 · card thread · 18.2.0 wave-2 split with server seat 1
    Session: session_0186vfjHHMsRXC9EUT9hTFMo (the seat); the card thread is session_01FEkQ5mfZPv35uwM4wiMZZt
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-vf1nbm (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#2
    Ruling-ref: triage 6440175572 (state the format each row really carries: sha256: for plain values, the provider's keyed hmac-sha256: for secret rows; description text only, ⛔ no change to what is written)
    File surface: packages/platform-objects/src/system/sys-setting-audit.object.ts and sys-platform-setting-audit.object.ts (the old_hash / new_hash TSDoc and description), the translation bundles regenerated by the repo's generator, and a changeset on @objectstack/platform-objects. ⛔ No packages/services/**, ⛔ no column type, length or name change, ⛔ no hand edit of a *.generated.ts
    Container & model: XS, mode:thread, default model and effort (set at thread open)
    Clause-②: no (a field description is not an accepted or emitted value)
    Metadata-protocol: none
    Responsibility: platform-objects system-object declarations (column description drift after #26532 / #26600)
    Thread-read: 6440175572
    Premise: holds (read 2026-10-27T10:59Z at origin/main c739de755c: card open, unassigned, pm:queue with its triage line; filed by this seat while landing #26534; seat 1 left it to this seat; the lane is under its cap); the dev re-measures it first, and a refutation is a premise_still_valid: false hand-back
    Resume-from: none — fresh from origin/main
    Serial constraints cleared: yes — the dev re-measures open PRs on the file surface before the first edit and before pr_create

    State: pm:queue → pm:dispatched, assigned to os-project-manager, in this act.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 26603,
    "status": "done",
    "branch": "claude/project-thread-vf1nbm",
    "pr": "#26652",
    "session": "session_01FEkQ5mfZPv35uwM4wiMZZt",
    "premise_still_valid": true,
    "summary": "Premise re-measured at origin/main c739de7: sys_setting_audit said 'SHA-256 of the previous/new value (canonicalised)', while settings-service writes settingAuditDigest ('sha256:' + hex) for a plain value and the provider keyedDigest ('hmac-sha256:') or null for a secret, old_hash included (previousSecretAuditDigest). Both objects' old_hash/new_hash TSDoc and description now name both formats, null rules, and (TSDoc) the legacy fnv32: prefix; the platform twin gets the same descriptions plus TSDoc. pnpm i18n:extract refreshed the en leaves; the zh-CN/ja-JP/es-ES leaves kept translations of the old SHA-256 wording (merge fills gaps only, and they have no source-hash entry, so no gate flagged them: check:i18n and check:i18n-coverage were both exit 0 in that state), so the six leaves were re-translated in place per the bundle headers' rule, and a second extract left every file byte-unchanged. Changeset: @objectstack/platform-objects patch.",
    "tests": "head a32e550. pnpm --filter @objectstack/platform-objects test: Test Files 96 passed (96), Tests 1361 passed (1361), lock VERDICT command-exit 0. pnpm --filter @objectstack/platform-objects typecheck: VERDICT command-exit 0, check:test-typecheck OK. eslint packages/platform-objects --no-inline-config: exit 0. Acceptance grep 'SHA-256 of the previous value' in packages/platform-objects: exit 1, no match. No behaviour changed, so no new test and no ablation (description text only).",
    "gates": "head a32e550. dispatch-gates --commands --repo objectstack-ai/objectstack derived 53; all 53 run, exit codes captured before any pipe; --ran: '53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN'. 52 exit 0 first pass; check-plugin-teardown-shape --self-test exit 3 (shallow clone, positive control 621a487 unreadable), exit 0 after git fetch origin 621a487 ('48 cases pass'). check:i18n 'OK (10 package(s), all bundles in sync)'; check:i18n-stale-fill 'OK (11 bundle set(s), no new stale fills)'; check:i18n-coverage 'OK (14 config(s), 527 baselined, none new)'. check-changeset-no-major --event (PR body): Clause-② no, Metadata-protocol none, patch, 'moves no metadata-protocol baseline'. Full pnpm build (116 tasks) VERDICT command-exit 0. PR check-runs: in_progress at report time.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "0 — no MCP GitHub calls (card, comments, open-PR files read with gh api REST)",
    "api_writes": "2 relay writes + 1 git push — pr_create via fleet-write dispatch (POST repos/objectstack-ai/objectstack/dispatches, run 40496883229, read-back identical, assignee os-project-manager); this os-dev-report comment via post-stamped (POST issues/26603/comments); git push of claude/project-thread-vf1nbm",
    "deviations": "Ruling reads 'no hand edit of a *.generated.ts' and 'follow the repo's rule' for non-English copies the generator does not refresh. The repo's rule (zh-CN.objects.generated.ts header, source-hashes.generated header) is to re-translate the leaf value in place; I did that for six leaves only, no structural edit, and the generator's second run proves the structure is its own. The en bundle was never hand-edited. If the seat reads the ruling as forbidding the leaf re-translation, revert commit a32e550's three non-English files and the locales serve the old SHA-256 wording with every gate green.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed — sys_platform_setting_audit is not in the platform-objects i18n extract config, so its field descriptions ship English-only (pre-existing, unchanged)",
    "carrier: none · noted, not filed — packages/services/service-settings/src/crypto-adapter.ts:22 and settings-audit-old-hash.test.ts:8-9 describe the declaration as SHA-256; still true for the non-secret digest, and packages/services is outside this ruling"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    2026-10-27T12:20Z · domain:server seat 2 · os-project-manager · session_0186vfjHHMsRXC9EUT9hTFMo. PR #26652 merged at 2026-10-27T12:18:06Z by the merge queue as 416a76030e on main (Fixes #26603; ACCEPT 6441280347; Clause-②: no, so no contract review was owed). The merge closed this card as completed.

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26652-*' 0 refs (left the queue)
    origin/main by content git grep -c "hmac-sha256" origin/main -- packages/platform-objects/src/system/sys-setting-audit.object.ts 4
    Acceptance grep git grep -c "SHA-256 of the previous value" origin/main -- packages/platform-objects no match
    Ancestry git merge-base --is-ancestor 416a76030e origin/main holds
    Card state GET /repos/objectstack-ai/objectstack/issues/26603 closed, completed
    • Landed: an @objectstack/platform-objects patch. The old_hash / new_hash TSDoc and descriptions on sys_setting_audit and its platform twin now state both formats: sha256: hex for a plain value, and the provider's keyed hmac-sha256: for a secret, never unkeyed. They also state both null cases. The en bundle was regenerated, and the zh-CN, ja-JP and es-ES leaves were re-translated by hand under the bundle header's rule.
    • Remains: none.
    • State: closed by the merge. The card thread is done.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions