Skip to content

[WIP] Create a new release version - #9

Closed
huangyiirene with Copilot wants to merge 1 commit into
mainfrom
copilot/create-new-release-version
Closed

[WIP] Create a new release version#9
huangyiirene with Copilot wants to merge 1 commit into
mainfrom
copilot/create-new-release-version

Conversation

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown
Contributor

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

发一个版本


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI requested a review from huangyiirene January 18, 2026 14:59
Copilot stopped work on behalf of huangyiirene due to an error January 18, 2026 14:59
os-zhuang added a commit that referenced this pull request Jun 15, 2026
…ure-function pattern, #1870) (#1926)

Long-term design for flow functions (per the templates evaluation): a flow
`function` is a PURE compute step — inputs → return value — and ALL data I/O
stays declarative on the flow graph. This keeps the data layer visible, governed
(RLS/tenancy/transactions via the engine's data path), and build-checkable
(create/update_record nodes the build already validates) — rather than giving
functions a raw data API that hides writes and bypasses governance. (Data-
lifecycle side effects remain L2 hooks, which legitimately get ctx.api.)

Two enablers:
- `config.outputVariable` exposes the function's return value as a flow variable
  → a later update_record persists it (`fields: { ai_category: '{ai.ai_category}' }`).
- `config.inputs` are now interpolated against live flow variables, so a function
  can consume a prior node's output (`inputs: { ticketId: '{record.id}' }`).

Skill: automation pitfall #9 now teaches the pure-function pattern (function
returns → outputVariable → update_record; hooks for data side effects).
+1 end-to-end test (compute → outputVariable → downstream node interpolates it);
service-automation 202; check:skill-docs passes.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
xuyushun441-sys added a commit that referenced this pull request Jun 23, 2026
…mation) (#2240)

- spec: FieldSchema.requiredPermissions: string[] (passes through Field.* builders).
- plugin-security: a field whose requiredPermissions aren't all held by the caller's
  systemPermissions is masked on read and denied on write (AND-gate, strictest-wins
  over permission-set field grants). getObjectSecurityMeta now reads per-field
  requiredPermissions; foldFieldRequiredPermissions folds unmet ones into the
  FieldMasker map as {readable:false,editable:false}, reusing maskResults +
  detectForbiddenWrites — no masker signature change.
- liveness: classify field.requiredPermissions (live). api-surface unchanged.
- Tests: spec field (+3) + middleware read-mask/write-deny (+4).

D5 (package-seeded admin-maintainable per-object secure defaults) needs no new
code: stack.permissions already seeds sys_permission_set (incl. per-object +
per-field grants), admin-editable in Setup — it composes with D2 (private) + D1
(capability seeding). cloud sys_license is the worked example. Delegated admin (#9)
remains future per the ADR.

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jun 30, 2026
Prime Directive #9 only mandated the `OS_` prefix; the *shape* was
undocumented, so new vars drifted (e.g. a bare `OS_PINYIN_SEARCH` for a
boolean flag). Codify the structure observed across the existing vars:

- `OS_{DOMAIN}_{FEATURE}[_QUALIFIER]` — domain-grouped (AUTH/CORS/SSO/…)
- boolean flags → `_ENABLED` suffix (OS_SSO_ENABLED, OS_SEARCH_PINYIN_ENABLED)
- config values → `OS_{DOMAIN}_{NAME}` (OS_CLOUD_URL, OS_LOG_LEVEL)
- escape hatches → `OS_ALLOW_{X}`; opt-outs → `OS_SKIP_/OS_DISABLE_`
- test-only → `OS_TEST_*`/`OS_EXPECT_*`

Pre-existing non-conforming vars (OS_METADATA_WRITABLE, OS_EAGER_SCHEMAS,
OS_SERVER_TIMING) flagged as debt, not precedent.

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 30, 2026
…fuse to load under NODE_ENV=production (#4093) (#4126)

#4058 step 1 classified plugin-dev's fakes honestly and step 2 made the
dispatcher gate on that classification. Neither is enough for three of them,
for the same reason honest labelling was not enough for the analytics shim
(#3891): the label was accurate while the behaviour still inverted the decision
it stood in for.

    security.permissions → checkObjectPermission() { return true; }   // allow-all
    security.rls         → compileFilter()        { return null; }    // no predicate
    security.fieldMasker → maskResults(r)         { return r; }       // unmasked

ADR-0076 D12's own line, learned from #3891, is that a fallback may degrade
features but NEVER security semantics — and the shim it retired merely dropped
the caller's RLS scoping, where these answered "allowed" outright.
`spec/src/contracts/security-service.ts` states it from the other side: these
three are plugin-security's implementation internals, and access-narrowing
answers must fail CLOSED. A fake registered under those names by a different
package is precisely the opposite.

Triggering it required nothing exotic: plugin-dev loads SecurityPlugin through
the same optional dynamic import as everything else, so `@objectstack/
plugin-security` merely not being installed swapped real RBAC/RLS/masking for
allow-all behind one `warn` line.

The slots now stay empty — what production has without SecurityPlugin, and what
the consumers already handle: enforcement lives inside the plugin's own
registered hooks, and the only reader of a slot (plugin-hono-server's
`/auth/me/permissions` and `/me/apps`) resolves it defensively and fails open on
presentation only, over data the read path already enforced. The boot log now
states plainly that RBAC, RLS and field masking are unenforced.

Second half, from the same finding: plugin-dev now REFUSES to initialize under
`NODE_ENV=production`. It is a published package that registers fakes for every
unclaimed core slot, including ones that report success for work they never
did, and it had no environment check of its own. Failing the boot is the right
response: such a process is misconfigured in a way no runtime behaviour can
make safe. `OS_ALLOW_DEV_PLUGIN=1` (the `OS_ALLOW_{X}` escape-hatch shape,
Prime Directive #9) overrides it for the deliberate cases.

Also: `/auth/me/permissions` resolves `security.permissions` and `metadata`
through the same guarded lookup its three sibling lookups already used — an
unregistered slot previously landed in the outer catch and was logged as
"/auth/me/permissions failed" on every console navigation instead of taking
the deliberate `!evaluator` branch.

Out of scope, filed as #4113 and blocking the `auth` half of #4093's A tier:
the dispatcher's `/auth` domain carries its OWN mock fallback which answers any
email + any password with 200 and a fabricated 24h session token, lives in
packages/runtime rather than an opt-in dev plugin, and gates on nothing but "no
auth service registered".

Verified: plugin-dev 12, plugin-hono-server 132, plugin-security 677, runtime
923, objectql 1183 pass; build 71/71; eslint clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 30, 2026
… the most rounds (#4152)

Both written from one branch's lifetime, so every row is something actually hit
rather than something that might happen.

#9 — refresh a long-lived worktree's build state after merging main. Four stale
artefacts each fail AS IF your change broke something, naming other people's
exports, other packages' files, or config you never touched:

  packages/spec/dist          check:api-surface reports OTHER people's exports as
                              "N breaking"; check:i18n-coverage rejects an example
                              config for a value the spec allows
  node_modules                a package cannot resolve a dependency it declares
  runtime/.objectstack/       fixture rows accumulating across runs
  .cache/objectui-*           dozens of lint errors in files never opened

None is CI-visible — CI checks out fresh and installs clean — so the whole cost
lands on whoever is debugging, which is exactly why it is worth recognising in one
step instead of re-diagnosing per gate. Also records that OS_SKIP_DTS=1 leaves no
.d.ts, so gen:api-surface cannot run under it at all.

#10 — a clean merge is not a working merge. Git conflicts on overlapping lines and
says nothing when two changes are individually fine and jointly wrong. Both
examples are recent: a test pinning a response body's exact shape landed while
that shape was being changed elsewhere (merged clean, failed CI), and a domain
file was deleted while another agent's guard still declared it (caught only
because the guard existed). Hence pull main and re-run before opening a PR, and
again before merging.


Claude-Session: https://claude.ai/code/session_01CYbS3kS8xzsHNXFTzp4e2z

Co-authored-by: Claude <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 30, 2026
… is gone (#3438) (#4213)

Executes the D2 half of ADR-0104's 2026-07-30 addendum: the warn-first window
closes in 17.0 rather than 18.0.

- actionParamsStrict() becomes laxActionParams(); enforcement is the default
  and OS_ALLOW_LAX_ACTION_PARAMS=1 is the only knob, spelled OS_ALLOW_* per
  PD #9 and ADR-0110 D6 — whose sole cited exception this removes.
  OS_ACTION_PARAMS_STRICT_ENABLED never reached `latest` (RC-only), so it is
  deleted outright rather than deprecated for a release.
- The opt-out path still warns once per action: opting out tolerates the
  drift rather than hiding it again.
- Dogfood duals inverted — the default path is now what the gate proves, and
  the hatch gets the test so the branch nobody sets cannot rot.

Also corrects docs the flip falsifies, plus two passages #3681 had left
self-contradictory in the v17 notes (hard rejection described as arriving only
via OS_DATA_VALUE_SHAPE_STRICT_ENABLED two paragraphs before saying media
enforces per verified deployment; the upgrade checklist prescribed that env var
as the route, which would opt in every value class including ones with no
migration behind them).
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.

2 participants